简体   繁体   English

流星:在电子邮件验证确认上做些什么

[英]Meteor: Do Something On Email Verification Confirmation

On my server I made accounts require email verification and to send the verification email: 在我的服务器上,我使帐户需要进行电子邮件验证并发送验证电子邮件:

Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});

I read somewhere online that the verification link will redirect the user to the home page of the web app once clicked. 我在网上某处读到,一旦单击验证链接,用户就会重定向到Web应用程序的主页。

On that home page I try to catch the first time it gets confirmed as I would like to add some entries to the MONGO DB the FIRST TIME the email gets verified and the user gets authenticated. 在该主页上,我尝试捕获首次确认的消息,因为我想在第一次通过电子邮件验证并验证用户身份的同时向MONGO DB添加一些条目。

So I try to get this confirmation on the client side by doing this: 因此,我尝试通过执行以下操作在客户端获得此确认:

Template.home.created = function(){
      if (Accounts._verifyEmailToken) {
        Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
          if (err != null) {
            if (err.message = 'Verify email link expired [403]') {
              console.log('Sorry this verification link has expired.')
            }
          } else {
            console.log('Thank you! Your email address has been confirmed.')

          }
        });
      }
    }

Unfortunately I NEVER got console.log('Thank you! Your email address has been confirmed.') to log in the console..... I always get console.log('Sorry this verification link has expired.') even after the first time I click on it. 不幸的是,我从来没有得到console.log('Thank you! Your email address has been confirmed.')登录控制台.....我总是得到console.log('Sorry this verification link has expired.')我第一次点击它。

What am I missing here??? 我在这里想念什么???

How do I get a function to be called the first time the email gets verified??? 我如何在首次验证电子邮件时获得要调用的功能???

Thank you. 谢谢。

Your error message verification is wrong: you are doing an assignment instead of a conditional check. 您的错误消息验证错误:您正在执行分配而不是条件检查。

if (err.message = 'Verify email link expired [403]') // WRONG!
if (err.message == 'Verify email link expired [403]') // this is a condition

I suggest you output the contents of err.message to move forward, because it may not be related to link expiration at all! 我建议您输出err.message的内容以继续前进,因为它可能根本与链接过期无关!

Template.home.created = function(){
  if (Accounts._verifyEmailToken) {
    Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
      if (err != null) {
        console.log(err.message);
      } else {
        console.log('Thank you! Your email address has been confirmed.')
      }
    });
  }
}

Ok....after playing around with the options.....I found this to work. 好的....玩完这些选项后.....我发现它可以正常工作。 The only downside is that a warning shows up in the console. 唯一的缺点是控制台中会显示警告。 This is the warning: 这是警告:

Accounts.onEmailVerificationLink was called more than once. Only one callback added will be executed.

I believe this is because I am using accounts-ui package.....and perhaps accounts-ui uses Accounts.onEmailVerificationLink as well and now we are overriding it..... 我相信这是因为我正在使用accounts-ui程序包.....,也许accounts-ui也使用Accounts.onEmailVerificationLink ,现在我们将其覆盖.....

This is the solution: 这是解决方案:

Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});

    if(Meteor.isClient){

      Accounts.onEmailVerificationLink(function(token, done){
        console.log('inside onEmailVerificationLink');
        console.log('token');
        console.log(token);

        Accounts.verifyEmail(token, function(err) {
          if (err != null) {
            console.log(err.message);
          } else {
            console.log('Thank you! Your email address has been confirmed.')
          }
        });

      });
    }


    if(Meteor.isServer){
      Accounts.onCreateUser(function(options, user){

         console.log('inside onCreateUser');
         return user;
      });

    }

Two potential solutions: 两种可能的解决方案:

Solution #1 解决方案1

Use monkey patching to intercept the call to the callback passed to verifyEmail() so that you can do what you want in addition to calling the original callback. 使用verifyEmail() patching截取传递给verifyEmail()的回调的调用,以便除了调用原始回调之外,还可以执行所需的操作。 Something like this (untested): 像这样(未经测试):

Accounts.verifyEmail = _.wrap(Accounts.verifyEmail, function (origVerifyEmail, token, callback) {
  return origVerifyEmail.call(Accounts, token, _.wrap(callback, function (origCallback, err) {
    try {
      if (! err) {
        // Add entries to the DB here
      }
    } finally {
      return origCallback.apply(null, _.rest(arguments));
    }
  }));
});

Note that if you use the above approach, you will presumably still need the server to ensure that the user's email address is in fact verified (ie the user's emails array contains an object with verified: true ) before actually adding stuff to the DB. 请注意,如果使用上述方法,则可能仍需要服务器确保实际上已验证用户的电子邮件地址(即,用户的emails数组包含一个带有verified: true的对象),然后才将内容实际添加到数据库。 For that reason, you might prefer... 因此,您可能更喜欢...

Solution #2 解决方案#2

On the server, watch the Meteor.users collection for changes to the verification status of email addresses. 在服务器上,观察Meteor.users集合以查看电子邮件地址的验证状态更改。 Something like this (untested): 像这样(未经测试):

Meteor.users.find().observe({
  changed: function (oldUser, newUser) {
    if (! _.findWhere(oldUser.emails, { verified: true }) &&
      _.findWhere(newUser.emails, { verified: true })) {
      // Add entries to the DB here
    }
  }
});

If an email is already verified, verifyEmail function will return the Error: Verify email link expired [403] error. 如果已验证电子邮件,则verifyEmail函数将返回Error: Verify email link expired [403]错误。

Make sure that you are only sending the verification token to an unverified email address, if you call the resetPassword function the email will automatically be verified. 确保仅将验证令牌发送到未验证的电子邮件地址,如果调用resetPassword函数,则将自动验证电子邮件。

It could be that you tested the verification token once on an account and it verified the email and then when you tried again it gave you the link expired error. 可能是您在一个帐户上测试了一次验证令牌,然后验证了电子邮件,然后再次尝试时,它给您链接过期错误。

A good way to test if the email is verified is to add the following snippet of code to your dashboard (or wherever the page goes when {{#if currentUser}} condition is true): 测试电子邮件是否通过验证的一种好方法是将以下代码段添加到您的仪表板(或{{#if currentUser}}条件为true时页面所处的位置):

<p>
    {{#if currentUser.emails.[0].verified}}
        <p>Email is verified</p>
    {{else}}
        <p>Email is not verified</p>
    {{/if}}
</p>

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM