我通过复制VS 2013模板中的代码在我的MVC应用程序中实现了ASP.NET Identity。基本的事情是工作,但我无法使重置密码工作。当我显示"忘记密码"页面生成包含令牌的电子邮件。该标记由以下方法返回:
UserManager.GeneratePasswordResetTokenAsync(user.Id)
当我点击链接时,重置密码表单打开,并允许用户输入他们的电子邮件地址和新密码。然后调用更改密码功能:
UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
这对我来说很好看,但结果总是一个"无效的令牌"而且我不明白为什么会这样。
有没有人知道它为什么不起作用?地狱存储在哪里?我认为它必须在AspNetUsers
表...
答案 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);