第二次调用 Accounts.sendVerificationEmail 时无法验证电子邮件令牌

Can't validate email token when calling Accounts.sendVerificationEmail a second time

我安装了使用 Meteor 帐户验证电子邮件地址的程序。它工作正常,但是当第二次调用 Accounts.sendVerificationEmail() 时,Account.verifyEmail() 方法总是以 403 拒绝:Verify email link expired 在调用新令牌时。

第一次调用 Accounts.sendVerificationEmail() 时在 Meteor.users 中设置的电子邮件验证令牌在再次调用该方法时不会更改:它仍然是随第一封电子邮件一起发送的 link工作。

我在 Meteor 文档或互联网上找不到与此相关的任何信息。在第二次调用 Accounts.sendVerificationEmail() 之前有什么事情要做吗(比如清理什么的?)。

当您使用 sendVerificationEmail() 时,用户集合中会出现一个新条目:'services.email.verificationTokens',您会在 'emails.[x].verified' 中看到它是 false。 当您使用 verifyEmail() 时,'emails.[x].verified' 变为真,'services.email.verificationTokens' 中的值消失。因此,如果您尝试第二次使用 verifyEmail(),则无法使用,因为电子邮件仍然经过验证并且验证令牌已被删除。 如果您第二次使用新令牌发送 sendVerificationEmail(),新的 link 允许您使用 verifyEmail() 而不会出现错误消息。

我在实施重新发送 link 到我的网站时遇到了同样的问题。我通过删除所有以前的 verficationTokens.

来解决这个问题

以下是解决此问题的两种方法:

  1. 如果您的活动数据库中有 n 数量的用户无法验证其帐户,则这是首选方法。在调用 Accounts.sendVerificationEmail() 方法后将此代码放在单独的 Meteor.call() 方法中:

    Meteor.users.update({_id: Meteor.userId()}, {'$push': services.email.verificationTokens": {$each: [], $slice: -1}}});

这将清空所有其他标记,除了最近调用 Accounts.sendVerificationEmail() 方法创建的最后一个标记。

  1. 此方法对于实施较新的项目或在新项目中实施 meteor-accounts 可能会更快。与步骤 1) 类似,将此代码放在新的 Meteor.call() 方法中,并在调用 Accounts.sendVerificationEmail() 方法后调用它:

    Meteor.users.update({_id: Meteor.userId()}, {'$pop': {"services.email.verificationTokens": -1}});

这将弹出 verificationTokens 的第一个条目,因此唯一的条目将保留在 Accounts.sendVerificationEmail() 方法中生成的最新令牌。

希望这对您有所帮助。