在Meteor中正确使用onResetPasswordLink,onEnrollmentLink和onEmailVerificationLink方法 [英] Using onResetPasswordLink, onEnrollmentLink, and onEmailVerificationLink methods properly in Meteor

查看:37
本文介绍了在Meteor中正确使用onResetPasswordLink,onEnrollmentLink和onEmailVerificationLink方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有人会提供一个Meteorpad或代码示例,以在Meteor中正确使用上面列出的一种方法(使用iron:router).我正在努力了解这些方法与我的应用程序之间如何精确交互,并且这些方法似乎很新,以至于没有太多关于如何正确使用它们的很好的文档.谢谢!

I was wondering if someone would be kind enough to provide a meteorpad or code example of using one of the methods listed above properly in Meteor (with iron:router). I'm struggling to understand how exactly these methods interact with my app, and it seems these methods are new enough that there isn't much good documentation on how to use them correctly. Thanks!

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

推荐答案

好,所以我将在这里发布我最终学习和做的事情,以便其他人可以将其用作参考.我也会尽力解释发生了什么.

Ok, so I am going to post what I ended up learning and doing here so others can use it as a reference. I'll do my best to explain what is happening as well.

从其他注释中可以看出,传递给Accounts.on **** Link回调的完成"功能是使我绊倒的主要部分.此功能仅做一件事-重新启用自动登录.值得注意的是,完成"功能/自动登录是核心帐户"软件包之一的一部分,无法修改.在一种特定情况下使用'autoLogin':用户A尝试在当前登录用户B的计算机上重置其密码.如果用户A在提交新密码之前退出了重置密码流,则用户B将保持登录状态进入.如果用户A完成了重置密码流程,则用户B将注销,而用户A将登录.

As can be seen in the other comments, the 'done' function passed to the Accounts.on****Link callback was the main part that tripped me up. This function only does one thing - re-enables autoLogin. It's worth noting that the 'done' function/autoLogin is a part of one of the core 'accounts' packages, and cannot be modified. 'autoLogin' is used in one particular situation: User A tries to reset his or her pw on a computer where User B is currently logged in. If User A exits the reset password flow before submitting a new password, then User B will remain logged in. If User A completes the reset password flow, then User B is logged out and User A is logged in.

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

The pattern used to handle 'done' in the accounts-ui package, and what I ended up doing, assigns 'done' to a variable that can then be passed to your template event handler function, and run once your reset password logic is complete. This variable assignment needs to be done in the Accounts.on****Link callback, but the callback can be placed in any top-level client side code (just make sure you assign the scope of the variables correctly). I just put it at the start of my reset_password_template.js file (I've only done this for resetting passwords so far, but the pattern should be similar):

client/reset_password_template.js:

client/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
});

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

The other challenge of using these on****Link callbacks is understanding how your app 'knows' the callback has been fired, and what needs to be done by the app. Since iron:router is so tightly integrated with Meteor, it's easy to forget it is a separate package. It's important to keep in mind these callbacks were written to operate independently of iron:router. This means when the link sent to your email is clicked, your app is loaded at the root level ('/').

***注意事项-StackOverflow上还有一些其他答案,这些答案提供了与iron:router集成并为每个链接加载特定路由的方法.这些模式对我来说,问题在于它们似乎有点破旧,与流星"方式不符.更重要的是,如果核心Meteor团队决定更改这些注册链接的路径,则这些路由将中断.我尝试调用Router.go('path');在on **** Link回调中,但是由于某些原因,这在Chrome和Safari中不起作用.我很想有一种方法来处理每个通过电子邮件发送的链接的特定路由,从而消除了不断设置和清除Session变量的需要,但是我想不出一个行之有效的解决方案.

***Side note - There are some other answers here on StackOverflow that offer ways to integrate with iron:router, and load a specific route for each link. The problem for me with these patterns was that they seemed a bit hackish, and not in line with the 'meteor' way. More importantly, if the core Meteor team decides to alter the path of these registration links, these routes would break. I tried calling Router.go('path'); in the on****Link callback, but for some reason this didn't work in Chrome and Safari. I would love to have a way to handle specific routes for each of these emailed links, thus eliminating the need for constantly setting and clearing Session variables, but I couldn't think of a good solution that worked.

无论如何,正如@stubailo在他的答案中所述,您的应用程序已加载(在根级别),并且触发了回调.触发回调后,就可以设置会话变量了.您可以使用以下会话模式使用此会话变量在根级别加载适当的模板:

Anyways, as @stubailo described in his answer, your app is loaded (at the root level), and the callback is fired. Once the callback is fired, you have your session variable set. You can use this session variable to load the appropriate templates at the root level using the following pattern:

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

client/home.html (or your landing page template)

{{#unless resetPasswordToken}}
  {{> home_template}}
{{else}}
  {{> reset_password_template}}
{{/unless}}

有了这个,您需要在reset_password_template.js文件和home.js中处理的事情很少:

With this, there are few things you need to take care of in your reset_password_template.js file, and home.js:

client/home.js

client/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');
  }
});

client/reset_password_template.js

client/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;
  }
});

希望这对其他尝试构建自己的自定义身份验证表单的人很有帮助.在其他情况下,其他答案中提到的软件包非常有用,但有时您需要通过软件包无法获得的其他自定义.

Hopefully this is helpful for others who are trying to build their own custom auth forms. The packages mentioned in the other answers are great for many cases, but sometimes you need additional customization that isn't available via a package.

这篇关于在Meteor中正确使用onResetPasswordLink,onEnrollmentLink和onEmailVerificationLink方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆