【发布时间】:2015-04-28 18:40:56
【问题描述】:
ASP.NET 身份正在返回“无效令牌”。为用户重置密码时的响应。
我尝试了以下方法:
- 在发送电子邮件之前对代码进行 URL 编码
- URL 编码和解码前后的代码
- 复制代码以确保它与发送的内容匹配
- 确保我的用户电子邮件得到确认(我听说这可能是个问题)
- 创建了自定义 UserManager/Store 等。
这是我的电子邮件代码:
var user = await UserManager.FindByNameAsync(model.Email);
var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
var callbackUrl = Url.Action("ResetPassword", "Account", new { code }, "http");
var body = string.Format("Click here to reset your password: {0}", callbackUrl);
await UserManager.SendEmailAsync(user.Id, "Reset Password", body);
return View("~/Views/Account/Login.cshtml", model);
生成的网址:
http://localhost/Account/ResetPassword?code=XTMg3fBDDR77LRptnRpg7r7oDxz%2FcvGscq5Pm3HMe8RJgX0KVx6YbOeqflvVUINipVcXcDDq1phuj0GCmieCuawdgfQzhoG0FUH4BoLi1TxY2kMljGp1deN60krGYaJMV6rbkrDivKa43UEarBHawQ%3D%3D
最后是我的重置代码:
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
ModelState.AddModelError("","Invalid Password Please Try Again");
return View();
结果里面是1个错误,Invalid token.
我的创建 UserManager 方法:
public static CustomerUserManager Create(IdentityFactoryOptions<CustomerUserManager> options, IOwinContext context)
{
var manager = new CustomerUserManager(new CustomerUserStore(context.Get<CustomerDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<Customer>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
manager.EmailService = new EmailService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<Customer, string>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
我的 Startup.Auth 配置:
app.CreatePerOwinContext(CustomerDbContext.Create);
app.CreatePerOwinContext<CustomerUserManager>(CustomerUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity =
SecurityStampValidator.OnValidateIdentity<CustomerUserManager, Customer, string>
(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: (id) => (id.GetUserId())
)
}
});
尝试过的解决方案列表:
- ASP.NET Identity 2 - UserManager.ConfirmEmail Fails In Production
- aspnet identity invalid token on confirmation email
- http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset#reset
- Asp.NET - Identity 2 - Invalid Token Error
- aspnet identity invalid token on confirmation email
- https://aspnetidentity.codeplex.com/discussions/544368
感谢您对此问题的任何帮助。
【问题讨论】:
-
看起来代码本身是 Base 64 编码的。告示符号是末尾的双等号 (%3D%3D)。查看数据库中的令牌并将其与您刚刚收到的令牌进行比较。还要确保在您收到电子邮件之前没有令牌过期从数据库中清除令牌。
标签: asp.net-mvc asp.net-identity asp.net-identity-2