我正在使用 Asp.Net-Identity-2, 并且尝试使用以下方法来验证电子邮件验证代码。但是我收到 “无效令牌” 错误消息。
我的应用程序的用户管理器是这样的:
public class AppUserManager : UserManager<AppUser>
{ public AppUserManager(IUserStore store) : base(store) { }
public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context) { AppIdentityDbContext db = context.Get<AppIdentityDbContext>(); AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db)); manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = false, RequireDigit = false, RequireLowercase = true, RequireUppercase = true }; manager.UserValidator = new UserValidator<AppUser>(manager) { AllowOnlyAlphanumericUserNames = true, RequireUniqueEmail = true }; var dataProtectionProvider = options.DataProtectionProvider; //token life span is 3 hours if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<AppUser> (dataProtectionProvider.Create("ConfirmationToken")) { TokenLifespan = TimeSpan.FromHours(3) }; } manager.EmailService = new EmailService(); return manager; } //Create
} //class } //namespace
我生成令牌的操作是(即使我在此处检查令牌,也会收到“无效令牌”消息):
[AllowAnonymous]
[HttpPost] [ValidateAntiForgeryToken] public ActionResult ForgotPassword(string email) { if (ModelState.IsValid) { AppUser user = UserManager.FindByEmail(email); if (user == null || !(UserManager.IsEmailConfirmed(user.Id))) { // Returning without warning anything wrong… return View(“../Home/Index”);
} //if string code = UserManager.GeneratePasswordResetToken(user.Id); string callbackUrl = Url.Action("ResetPassword", "Admin", new { Id = user.Id, code = HttpUtility.UrlEncode(code) }, protocol: Request.Url.Scheme); UserManager.SendEmail(user.Id, "Reset password Link", "Use the following link to reset your password: <a href=\"" + callbackUrl + "\">link</a>"); //This 2 lines I use tho debugger propose. The result is: "Invalid token" (???) IdentityResult result; result = UserManager.ConfirmEmail(user.Id, code); } // If we got this far, something failed, redisplay form return View();
} //ForgotPassword
我检查令牌的操作是(在这里,当我检查结果时,我总是得到“无效令牌”):
public async Task ResetPassword(string id, string code) {
if (id == null || code == null) { return View("Error", new string[] { "Invalid params to reset password." }); } IdentityResult result; try { result = await UserManager.ConfirmEmailAsync(id, code); } catch (InvalidOperationException ioe) { // ConfirmEmailAsync throws when the id is not found. return View("Error", new string[] { "Error to reset password:<br/><br/><li>" + ioe.Message + "</li>" }); } if (result.Succeeded) { AppUser objUser = await UserManager.FindByIdAsync(id); ResetPasswordModel model = new ResetPasswordModel(); model.Id = objUser.Id; model.Name = objUser.UserName; model.Email = objUser.Email; return View(model); } // If we got this far, something failed. string strErrorMsg = ""; foreach(string strError in result.Errors) { strErrorMsg += "<li>" + strError + "</li>"; } //foreach return View("Error", new string[] { strErrorMsg });
} //ForgotPasswordConfirmation
我不知道可能遗漏了什么或出了什么问题…
由于您在此处生成用于重置密码的令牌:
string code = UserManager.GeneratePasswordResetToken(user.Id);
但是实际上尝试验证电子邮件的令牌:
result = await UserManager.ConfirmEmailAsync(id, code);
这是2个不同的令牌。
在您的问题中,您说您正在尝试验证电子邮件,但是您的代码用于密码重置。你在做什么
如果您需要电子邮件确认,请通过生成令牌
var emailConfirmationCode = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
并通过确认
var confirmResult = await UserManager.ConfirmEmailAsync(userId, code);
如果您需要重置密码,请生成以下令牌:
var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
并确认如下:
var resetResult = await userManager.ResetPasswordAsync(user.Id, code, newPassword);