繁体   English   中英

ASP.NET Identity 2.2.1 - 发送包含代码的确认电子邮件,而不是链接

[英]ASP.NET Identity 2.2.1 - send confirmation email with code, not with link

我已经使用ASP.NET Identity 2.2.1成功构建了简单的注册系统。
我只需要API,所以我构建了一个简单的控制器,允许使用route account/create创建帐户,当创建帐户时,用户会收到带有令牌以确认他的电话所需的短信,同时我正在生成验证电子邮件所需的链接地址,我将其发送到用户的电子邮件地址。 然后用户需要从SMS输入令牌(请求到account/confirm_phone )并点击他收到的电子邮件中的链接。
激活帐户需要这两个操作,这部分工作正常。

我要求将电子邮件链接更改为电子邮件令牌,类似于用于确认电话号码的电子邮件令牌,因此用户不必点击链接就必须输入该令牌(请求account/confirm_email

方法GenerateEmailConfirmationTokenAsync返回非常长的代码,成为电子邮件中链接发送的一部分,我希望它返回6位数的令牌。

我无法重复使用GeneratePhoneConfirmationTokenAsync因为这将生成与通过SMS发送相同的令牌。

我通过互联网搜索,我无法找到任何有关如何自定义GenerateEmailConfirmationTokenAsync方法生成的令牌的信息。

是否可以配置该令牌生成器,以便它将返回6(或任何可配置长度)数字代码,我可用于确认用户电子邮件地址。

我知道链接发送给用户是更好的选择,但正如我写的这是我得到的要求,我不能改变它。

我对此有一个仔细的审视,我担心你运气不好。

ASP.Net Identity框架(v2.2.x)有2个令牌提供程序: DataProtectorTokenProviderEmailTokenProvider

DataProtectorTokenProvider为您提供了一个非常长的令牌,对于手动复制粘贴不利。 但它允许设置时间跨度: DataProtectorTokenProvider.TokenLifespan 默认情况下,它设置为1天 - 请参阅该类的约束器。 此提供程序生成的令牌包含当前UTC时间,userId,安全戳和其他字符串purpose ,可以是任何内容,但在验证时,这必须与生成时相同。 这通常是“电子邮件”或“电话”。 然后,所有数据都由IDataProtector加密。 因此,你会得到一个非常长而令人讨厌的字符串。

您可以为不同的令牌设置可变的生命周期,但在验证每个特定令牌之前,您必须围绕在DataProtectorTokenProvider.TokenLifespan设置正确的值进行魔术舞蹈。

另一个选项EmailTokenProvider - 此类继承自TotpSecurityStampBasedTokenProvider 此令牌提供程序基于Rfc6238生成一次性密码(OTP)。 此令牌是时间敏感的,并且在传递时间窗口后变为无效。 有关详细信息,请参见第5.2节 身份的默认时间窗口设置为3分钟。 见行:

private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3);

Rfc6238AuthenticationService 但是Rfc6238表示实现必须允许超过1个时间窗口。 给定实现允许总共6分钟令牌寿命。 如果不实施自己的Rfc6238,就无法改变这种状况。

因此,Identity不会为您提供实现您的需求的方法 - 您必须自己生成令牌并将其与时间戳一起存储。 也许只有其中一个 - 具有较长寿命的短令牌。 默认的SMS实现已经是短暂的,并且是手动输入的简称。

这可能不是那么容易,但是这样做的方法是编写自己的IUserTokenProvider实现。

public class CustomTokenProvider : IUserTokenProvider<ApplicationUser, string>
{
    public Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task<bool> IsValidProviderForUserAsync(UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task NotifyAsync(string token, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task<bool> ValidateAsync(string purpose, string token, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }
}

然后在ApplicationUserManager的Create方法中:

manager.UserTokenProvider = new CustomTokenProvider<ApplicationUser, string>();

暂无
暂无

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

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