在Meteor中正确使用onResetPasswordLink,onEnrollmentLink和onEmailVerificationLink方法

bgm*_*ter 9 meteor iron-router meteor-accounts

我想知道是否有人能够提供一个meteorpad或代码示例,在Meteor中正确使用上面列出的方法之一(使用铁:路由器).我很难理解这些方法究竟是如何与我的应用程序交互的,而且看起来这些方法已经足够新,以至于没有很多关于如何正确使用它们的良好文档.谢谢!

http://docs.meteor.com/#/full/Accounts-onResetPasswordLink

bgm*_*ter 15

好的,所以我将发布我最终学习并在这里做的事情,以便其他人可以将它作为参考.我会尽力解释发生的事情.

从其他评论中可以看出,'done'函数传递给Accounts.on****Link回调是绊倒我的主要部分.此功能只执行一项操作 - 重新启用autoLogin.值得注意的是,'done'函数/ autoLogin是其中一个核心'account'包的一部分,并且无法修改.'autoLogin'用于某种特定情况:用户A尝试在用户B当前登录的计算机上重置他或她的pw.如果用户A在提交新密码之前退出重置密码流,则用户B将保持记录状态如果用户A完成重置密码流,则用户B注销,用户A登录.

用于处理accounts-ui包中的'done'的模式,以及我最终做的事情,将'done'分配给一个变量,然后可以将其传递给模板事件处理函数,并在重置密码逻辑完成后运行.此变量赋值需要在Accounts.on****链接回调中完成,但回调可以放在任何顶级客户端代码中(只需确保正确分配变量的范围).我只是把它放在我的reset_password_template.js文件的开头(到目前为止我只是为了重置密码而做了这个,但模式应该类似):

客户机/ reset_password_template.js:

// set done as a variable to pass
var doneCallback;

Accounts.onResetPasswordLink(function(token, done) {
  Session.set('resetPasswordToken', token);  // pull token and place in a session variable, so it can be accessed later 
  doneCallback = done;  // Assigning to variable
});
Run Code Online (Sandbox Code Playgroud)

在****Link回调中使用这些的另一个挑战是了解你的应用程序"知道"回调是如何被触发的,以及应用程序需要做什么.由于铁:路由器与Meteor紧密集成,因此很容易忘记它是一个单独的包.重要的是要记住这些回调是为了独立于铁运行而编写的:路由器.这意味着当点击发送到您的电子邮件的链接时,您的应用程序将在根级别('/')加载.

***附注 - StackOverflow上还有一些其他答案提供了与铁集成的方法:路由器,并为每个链路加载特定路由.对我来说,这些模式的问题在于它们看起来有点像hackish,并且不符合'流星'的方式.更重要的是,如果核心Meteor团队决定改变这些注册链接的路径,这些路线将会中断.我试过调用Router.go('path'); 在****链接回调中,但由于某种原因,这在Chrome和Safari中无效.我希望有办法处理每个电子邮件链接的特定路由,从而消除了不断设置和清除会话变量的需要,但我想不出一个有效的解决方案.

无论如何,正如@stubailo在他的回答中所描述的那样,你的应用程序被加载(在根级别),并且回调被触发.触发回调后,您将设置会话变量.您可以使用此会话变量使用以下模式在根级别加载相应的模板:

client/home.html(或您的目标网页模板)

{{#unless resetPasswordToken}}
  {{> home_template}}
{{else}}
  {{> reset_password_template}}
{{/unless}}
Run Code Online (Sandbox Code Playgroud)

有了这个,你需要在reset_password_template.js文件和home.js中处理几件事:

客户机/ home.js

// checks if the 'resetPasswordToken' session variable is set and returns helper to home template
Template.home.helpers({
  resetPasswordToken: function() {
    return Session.get('resetPasswordToken');
  }
});
Run Code Online (Sandbox Code Playgroud)

客户机/ reset_password_template.js

// if you have links in your template that navigate to other parts of your app, you need to reset your session variable before navigating away, you also need to call the doneCallback to re-enable autoLogin
Template.reset_password_template.rendered = function() {
  var sessionReset = function() {
    Session.set('resetPasswordToken', '');
    if (doneCallback) {
      doneCallback();
    }    
  }

  $("#link-1").click(function() {
    sessionReset();
  });

  $('#link2').click(function() {
    sessionReset();
  });
}

Template.reset_password_template.events({
  'submit #reset-password-form': function(e) {
    e.preventDefault();

    var new_password = $(e.target).find('#new-password').val(), confirm_password = $(e.target).find('#confirm-password').val();

    // Validate passwords
    if (isNotEmpty(new_password) && areValidPasswords(new_password, confirm_password)) {
      Accounts.resetPassword(Session.get('resetPasswordToken'), new_password, function(error) {
        if (error) {
          if (error.message === 'Token expired [403]') {
            Session.set('alert', 'Sorry, this link has expired.');
          } else {
            Session.set('alert', 'Sorry, there was a problem resetting your password.');          
          }
        } else {
          Session.set('alert', 'Your password has been changed.');  // This doesn't show. Display on next page
          Session.set('resetPasswordToken', '');
          // Call done before navigating away from here
          if (doneCallback) {
            doneCallback();
          }
          Router.go('web-app');
        }
      });
    }

    return false;
  }
});
Run Code Online (Sandbox Code Playgroud)

希望这对于那些试图构建自己的自定义身份验证表单的人有所帮助.其他答案中提到的软件包在很多情况下都很好,但有时您需要通过软件包无法进行的其他自定义.


stu*_*ilo 6

我写了这个方法,希望我能给出一个如何使用它的好例子.

它应Accounts.sendResetPasswordEmailAccounts.resetPassword(http://docs.meteor.com/#/full/accounts_sendresetpasswordemailhttp://docs.meteor.com/#/full/accounts_resetpassword)一起使用.

基本上,假设您想要实现自己的帐户UI系统,而不是使用accounts-ui包或类似的.如果您想要一个密码重置系统,您需要三件事:

  1. 一种使用密码重置链接发送电子邮件的方法
  2. 一种了解用户何时单击重置链接的方法
  3. 一种实际重置密码的方法

以下是流程应如何工作:

  1. 用户点击页面上显示"重置密码"的链接
  2. 您可以找到哪个用户(可能是让他们输入他们的电子邮件地址),然后打电话 Accounts.sendResetPasswordEmail
  3. 用户单击他们刚刚收到的电子邮件中的重置密码链接
  4. 您的应用已加载并注册回调 Accounts.onResetPasswordLink
  5. 调用回调是因为URL中有一个带有密码重置令牌的特殊片段
  6. 此回调可以显示一个特殊的UI元素,要求用户输入新密码
  7. 应用程序Accounts.resetPassword使用令牌和新密码进行调用
  8. 现在用户已登录并且他们有一个新密码

这有点复杂,因为它是最先进和自定义的流程.如果你不想浪费时间与所有这些回调和方法的,我会建议使用现有的帐户UI包之一,例如accounts-uihttps://atmospherejs.com/ian/accounts-ui-bootstrap-3

对于一些示例代码,请查看该accounts-ui软件包的代码:https://github.com/meteor/meteor/blob/devel/packages/accounts-ui-unstyled/login_buttons_dialogs.js