使用ASP.NET标识重置密码时令牌无效

时间:2014-12-02 04:01:40

标签: asp.net-mvc

我通过复制VS 2013模板中的代码在我的MVC应用程序中实现了ASP.NET Identity。基本的事情是工作,但我无法使重置密码工作。当我显示"忘记密码"页面生成包含令牌的电子邮件。该标记由以下方法返回:

UserManager.GeneratePasswordResetTokenAsync(user.Id)

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

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

这对我来说很好看,但结果总是一个"无效的令牌"而且我不明白为什么会这样。

有没有人知道它为什么不起作用?地狱存储在哪里?我认为它必须在AspNetUsers表...

附近的数据库中

5 个答案:

答案 0 :(得分:33)

ASP.NET身份中由UserManager生成的令牌通常包含" +"作为查询字符串传递的字符变为" " 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);

这应该可以解决问题。 我遇到了同样的问题并找到了答案here

答案 1 :(得分:31)

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

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

答案 2 :(得分:0)

在我的情况下,这是因为数据库中的数据是从另一个数据库错误导入的。 SecurityStamp字段为空,因此我收到了无效的令牌错误。

答案 3 :(得分:0)

如果您的SecurityStamp在生成令牌后发生更改,则该令牌也无效。

例如,您使用以下方式生成令牌

UserManager.GeneratePasswordResetTokenAsync(user.Id);

然后致电

UserManager.RemovePasswordAsync(user.Id);

您的SecurityStamp得到续订,因此令牌现在无效

答案 4 :(得分:0)

对我来说,安全邮票还可以。与接受的答案一致,我使用编码方法使用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);