一尘不染

Asp.NET Identity 2给出“无效令牌”错误

c#

我正在使用 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

  • 我检查令牌的操作是(在这里,当我检查结果时,我总是得到“无效令牌”):

    [AllowAnonymous]
    

    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

我不知道可能遗漏了什么或出了什么问题…


阅读 294

收藏
2020-05-19

共1个答案

一尘不染

由于您在此处生成用于重置密码的令牌:

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);
2020-05-19