24

我通过从 VS 2013 模板复制代码,在我的 MVC 应用程序中实现了 ASP.NET Identity。基本工作正常,但我无法让重置密码工作。当我显示“忘记密码”页面时,会生成一封包含令牌的电子邮件。此令牌由以下方法返回:

UserManager.GeneratePasswordResetTokenAsync(user.Id)

当我单击链接时,重置密码表单打开并让用户输入他们的电子邮件地址和新密码。然后调用更改密码功能:

UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);

这对我来说看起来不错,但结果总是“无效令牌”,我不明白为什么会这样。

有人知道为什么它不起作用吗?令牌到底存储在哪里?我认为它必须在AspNetUsers桌子周围某处的数据库中......

4

5 回答 5

46

UserManager由ASP.NET Identity生成的令牌通常包含“ +”字符,当作为查询字符串传递时,这些字符会在 URL 中更改为“”(空格)。在您的 ResetPassword ActionResult 中,将“ ”替换为“”,+如下所示:

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);

这应该够了吧。我遇到了同样的问题,在这里找到了答案。

于 2015-03-23T14:49:59.813 回答
34

只是想补充一点,除了 HTML 编码/解码之外,最常见的问题是您在数据库中的用户条目可能缺少 SecurityStamp。ASP.NET Identity 中存在一个错误,其中一个函数在创建令牌时将其设置为 null,而另一个在验证令牌时检查空字符串。

如果您的 SecurityStamp 为 null 或空字符串,这将导致无效令牌问题。

于 2015-06-10T16:51:56.210 回答
2

对我来说,安全印章没问题。与接受的答案一致,我使用 encode 方法对带有重置链接的代码进行编码HttpContext.Current.Server.UrlEncode,如下所示:

string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
string callbackUrl = ConfigurationManager.AppSettings["baseurl"] + "/resetpassword?email=" + user.Email + "&code=" + HttpContext.Current.Server.UrlEncode(code);
于 2018-07-29T04:37:25.613 回答
1

如果您SecurityStamp在生成令牌后进行了更改,则该令牌也无效。

因此,例如,您使用生成令牌

UserManager.GeneratePasswordResetTokenAsync(user.Id);

然后打电话

UserManager.RemovePasswordAsync(user.Id);

SecurityStamp更新,因此令牌现在无效

于 2018-07-13T09:53:22.540 回答
0

就我而言,这是因为数据库中的数据错误地从另一个数据库导入。SecurityStamp字段为空,所以我收到无效令牌错误。

于 2016-10-24T07:46:40.227 回答