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

Javascript 流星:在电子邮件验证确认上做点什么,javascript,node.js,meteor,meteor-accounts,Javascript,Node.js,Meteor,Meteor Accounts,在我的服务器上,我使帐户需要电子邮件验证并发送验证电子邮件: Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false}); 我在网上的某个地方读到,一旦单击验证链接,用户将重定向到web应用程序的主页 在该主页上,我试图捕捉第一次确认邮件,因为我想在第一次验证电子邮件和用户身份验证时向MONGO DB添加一些条目 因此,我尝试通过以下方式在客户端获得此确认: Template.home.c

在我的服务器上,我使帐户需要电子邮件验证并发送验证电子邮件:

Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});
我在网上的某个地方读到,一旦单击验证链接,用户将重定向到web应用程序的主页

在该主页上,我试图捕捉第一次确认邮件,因为我想在第一次验证电子邮件和用户身份验证时向MONGO DB添加一些条目

因此,我尝试通过以下方式在客户端获得此确认:

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.')

          }
        });
      }
    }
不幸的是,我从未获得
console.log('谢谢!您的电子邮件地址已确认')
登录控制台。。。。。 我总是得到
console.log('很抱歉,此验证链接已过期')
即使在我第一次单击它之后

我在这里错过了什么

如何在电子邮件第一次得到验证时调用函数


谢谢。

您的错误消息验证是错误的:您正在执行分配,而不是条件检查

if (err.message = 'Verify email link expired [403]') // WRONG!
if (err.message == 'Verify email link expired [403]') // this is a condition
我建议您输出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.')
      }
    });
  }
}

好的……在玩了这些选项之后……我发现这是可行的。 唯一的缺点是控制台中会出现警告。这是警告:

Accounts.onEmailVerificationLink was called more than once. Only one callback added will be executed.
我相信这是因为我使用的是accounts ui包…..也许accounts ui使用的是
accounts.onEmailVerificationLink
,现在我们正在覆盖它

这就是解决方案:

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

    }

两种可能的解决方案:

解决方案#1 使用monkey patching截获对传递给
verifyEmail()
的回调的调用,以便除了调用原始回调之外,还可以执行您想要的操作。类似这样(未经测试):

请注意,如果使用上述方法,您可能仍然需要服务器确保用户的电子邮件地址在实际向数据库添加内容之前得到验证(即,用户的
电子邮件
数组包含一个具有
verified:true
的对象)。出于这个原因,你可能更喜欢

解决方案#2 在服务器上,查看Meteor.users收集中电子邮件地址验证状态的更改。类似这样(未经测试):


如果电子邮件已验证,
verifyEmail
功能将返回
错误:验证电子邮件链接已过期[403]
错误

确保您只将验证令牌发送到未验证的电子邮件地址,如果您调用
resetPassword
功能,电子邮件将自动验证

可能是您在一个帐户上测试了验证令牌一次,它验证了电子邮件,然后当您再次尝试时,它给了您链接过期错误

测试电子邮件是否已验证的一个好方法是将以下代码片段添加到仪表板(或当
{{if currentUser}}
条件为true时,无论页面出现在何处):


{{#如果currentUser.emails[0]。已验证}
电子邮件已验证

{{else} 电子邮件未经验证

{{/if}


希望这有帮助

您可以尝试使用
Accounts.onLogin
callback在用户登录时侦听,并检查电子邮件是否已验证,以及是否在其中具有功能。但每次用户登录时都会调用该回调。我想在mongodb第一次进行身份验证或登录时添加mongodb条目,但绝对只添加一次…..您好,我现在使用的是上面的ur代码,但我仍然无法获得console.log(“谢谢!您的电子邮件地址已确认”。)登录。这意味着err仍然不是null,即使我第一次只单击了验证链接。你知道发生了什么吗?那么你从控制台.log(err.message)得到了什么?嗨,我收到了一条实际的错误消息:“错误:验证电子邮件链接过期[403]”…这是即使我第一次点击链接…这里可能有一场比赛…在进行回调之前,它首先得到验证…但我不知道如何修复它…这对我来说似乎是错误的,因为你在验证客户端上的电子邮件。我没有使用电子邮件验证,但正如您所指出的,account ui包使用此方法(它正在为其定义一个选项!),因此我相信它可以为您完成所有这些(即,软件包将自己的信息存储在users.service密钥下,并有一个电子邮件字段,已验证。我很确定,如果您激活该选项而不执行任何其他操作,您将由软件包更新该值,而不是自己验证。您好,是的,软件包会为您进行验证,但它不会提供一个“钩子”用于调用自定义函数。这就是为什么我需要这样做,以便将自定义代码放在console.log(“谢谢!您的电子邮件地址已被确认”)之后,这对我来说就像一个“钩子”。对于AccountsTemplates/UserAccounts,解决方案#1对我不起作用。
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));
    }
  }));
});
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
    }
  }
});
<p>
    {{#if currentUser.emails.[0].verified}}
        <p>Email is verified</p>
    {{else}}
        <p>Email is not verified</p>
    {{/if}}
</p>