[英]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个令牌提供程序: DataProtectorTokenProvider
和EmailTokenProvider
。
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.