【问题标题】:Meteor: Do Something On Email Verification ConfirmationMeteor:对电子邮件验证确认做一些事情
【发布时间】:2015-12-20 08:44:51
【问题描述】:

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

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

我在网上某处读到验证链接将在用户点击后将用户重定向到网络应用的主页。

在该主页上,我尝试捕捉第一次得到确认的信息,因为我想在第一次验证电子邮件并且用户通过身份验证时将一些条目添加到 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('Thank you! Your email address has been confirmed.') 登录控制台..... 即使在我第一次点击之后,我也总是得到console.log('Sorry this verification link has expired.')

我在这里错过了什么???

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

谢谢。

【问题讨论】:

  • 你可以尝试在用户登录时使用Accounts.onLogin回调来监听,并检查邮箱是否通过验证并有功能。
  • 但是每次用户登录时都会调用该回调。我想在第一次验证或登录时添加 mongodb 条目,但绝对只有一次.....跨度>

标签: javascript node.js meteor meteor-accounts


【解决方案1】:

你的错误信息验证是错误的:你正在做一个作业而不是一个条件检查。

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

【讨论】:

  • 嗨,我现在正在使用上面的代码,但我仍然没有得到 console.log('谢谢!您的电子邮件地址已被确认。') 来登录。这意味着即使我第一次单击验证链接,err 仍然不为空。有什么想法吗?
  • 那么你从console.log(err.message) 得到什么?
  • 嗨,我收到一条实际的错误消息:“错误:验证电子邮件链接已过期 [403]”......即使我第一次点击了链接......那里可能是一场比赛......在到达回调之前首先得到验证......但我不知道如何解决它......
【解决方案2】:

好的....在玩弄了这些选项之后......我发现这很有效。 唯一的缺点是控制台中会显示警告。这是警告:

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

    }

【讨论】:

  • 这对我来说似乎是错误的,因为您正在客户端上验证电子邮件。我没有使用电子邮件验证,但正如你指出的那样,account-ui 包使用这种方法(它正在为它定义一个选项!)所以我相信它会为你完成所有这些(即包将它自己的信息存储在users.service 键,并有一个电子邮件字段,已验证。我很确定如果您激活该选项而不做任何其他事情,您将通过包更新该值,而不是自己验证它。
  • 您好,是的,该软件包会为您进行验证,但它没有提供可用于调用自定义函数的“挂钩”。这就是为什么我需要这样做,以便我可以将我的自定义代码放在 console.log('Thank you! Your email address has been confirmed.') 之后,这对我来说就像一个“钩子”..
【解决方案3】:

两种可能的解决方案:

解决方案 #1

使用猴子补丁来拦截对传递给verifyEmail()的回调的调用,这样除了调用原始回调之外,您还可以做任何您想做的事情。像这样的东西(未经测试):

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

请注意,如果您使用上述方法,您可能仍然需要服务器来确保用户的电子邮件地址实际上是经过验证的(即用户的emails数组包含带有@的对象987654324@) 在实际向数据库添加内容之前。因此,您可能更喜欢...

解决方案 #2

在服务器上,观察Meteor.users 集合以了解电子邮件地址验证状态的变化。像这样的东西(未经测试):

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

【讨论】:

  • 使用 AccountsTemplates/UserAccounts,解决方案 #1 对我不起作用。
【解决方案4】:

如果电子邮件已经过验证,verifyEmail 函数将返回 Error: Verify email link expired [403] 错误。

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

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

测试电子邮件是否经过验证的一个好方法是将以下 sn-p 代码添加到您的仪表板(或当{{#if currentUser}} 条件为真时页面所在的任何位置):

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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2016-05-21
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 2017-09-13
    • 2017-02-07
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    相关资源
    最近更新 更多