我正在使用此代码生成密码重置链接:
private async Task<string> GetNewEmailConfirmationLink(ApplicationUser user)
{
var code = await this.UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action(
"ConfirmEmail",
"Account",
new { userId = user.Id, code = code },
protocol: Request.Url.Scheme);
return callbackUrl;
}
原则上,此代码工作正常 - 但生成的链接非常长。虽然安全,但有时需要复制粘贴此链接等,然后它的长度往往会导致错误(忘记元素等)。有没有办法缩短这个时间?
生成的链接示例:http://example.com:9999/de-DE/Account.aspx/ConfirmEmail?userId=1f4f605a-1be5-4b79-9fb0-139687fe8edc&code=0AjkI5qK917WkZw%2Bz0nXf1uK%2BK9bvYAK6BNEVM2l%2Fc%2BlBYOIiitrQ0gMUrB96CCNYc11hnpNpp2Wg2buC548mAb8l9JwzcwfuOiMAXiwJ%2F3iDH1LlXWgiLW%2FXxcVqLEs2hIhvmye2%2FJxQZD3RcODyNyGD%2FnWjrJRoFK%2B16FtyrtimfNRL%2F1L9vgrk5HiWENn
对于 ASP.NET Core,是的,我们可以做简短,不那么头疼的事情。
services.AddIdentity<ApplicationUser, ApplicationRole>(options => {
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
}).AddDefaultTokenProviders()
.AddEntityFrameworkStores<YourDbContext>();
有两种方法可以实现这一点。
一种是缩短生成的代码本身。这意味着您提供一个较短的版本(从原始代码生成)并将其用于所有用户交互。在确认用户的电子邮件地址之前,您将链接转换为其原始表示形式。
另一种选择是实现创建您自己的令牌的 IUserTokeProvider。
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
})
.AddDefaultTokenProviders();
经过一番挖掘后发现,默认EmailTokenProvider
准确地生成了您要查找的六位数字,但默认情况下它被包装到一个DataProtectorTokenProvider
中,这会扰乱输出。
通过"重置"EmailConfirmationTokenProvider
以TokenOptions.DefaultEmailProvider
解开包装并在调用 GenerateEmailConfirmationTokenAsync
方法时获取正常的解密令牌。
我看到我的答案与 https://stackoverflow.com/a/54523545/129269 相符,但在不知道背景的情况下我没有弄清楚。