我通过从VS 2013模板复制代码在我的MVC应用程序中实现了 ASP.NET Identity。基本的事情是有效的,但我无法让重置密码工作。当我显示"忘记密码"页面时,会生成一封包含令牌的电子邮件。此令牌由以下方法返回:
UserManager.GeneratePasswordResetTokenAsync(user.Id)
当我单击链接时,重置密码表单会打开,并允许用户输入他们的电子邮件地址和新密码。然后调用更改密码功能:
UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
这对我来说看起来不错,但结果总是"无效令牌",我不明白为什么会这样。
有人知道为什么它不起作用吗?令牌到底存储在哪里?我想它一定在AspNetUsers
表周围的数据库中......
UserManager
在 ASP.NET 身份中生成的令牌通常包含"+
"字符,当作为查询字符串传递时,这些字符在URL中会更改为""(空格)。在重置密码操作结果中,将 "
" 替换为 "
SecurityStamp
",如下所示:
var code = model.Code.Replace(" ", "+");
//And then change the following line
UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
//To this one so it uses the code(spaces replaced with "+") instead of model.Code
UserManager.ResetPasswordAsync(user.Id, code, model.Password);
这应该可以解决问题。我遇到了同样的问题,并在这里找到了答案。
只是想补充一点,HTML编码/解码之外最常见的问题是您在数据库中的用户条目可能缺少SecurityStamp。ASP.NET Identity 中存在一个错误,其中一个函数在创建令牌时将其设置为 null,而另一个函数在验证令牌时检查空字符串。
如果您的安全戳为空或空字符串,这将导致无效令牌问题。
安全印章还可以。与接受的答案内联,我使用 encode 方法使用 SecurityStamp
对带有重置链接的代码进行编码,如下所示:
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
string callbackUrl = ConfigurationManager.AppSettings["baseurl"] + "/resetpassword?email=" + user.Email + "&code=" + HttpContext.Current.Server.UrlEncode(code);
如果在生成令牌后SecurityStamp
发生变化,则令牌也无效。
因此,例如,您使用生成令牌
UserManager.GeneratePasswordResetTokenAsync(user.Id);
然后打电话
UserManager.RemovePasswordAsync(user.Id);
您的CC_9已续订,因此令牌现在无效
就我而言,这是因为数据库中的数据不正确地从另一个数据库导入。 CC_10字段为空,所以我得到无效的令牌错误。