ithieme1
ithieme1

Reputation: 45

ASP.NET Identity Password Reset Token

When I try to reset a password, I'm getting the "Invalid Token"

Token before being sent: cBcZbiN8LO9+aIVMbegaj1k5IYrJ3fBOKJ/WSH0NZZUgguSgWOFANoVOMp8y5b/481AP/mpnusV1YlmXQ1zFQmi4S/7xYMtRn3IeSIviEWmuxwPF8O41Y1pFQ1tF8GAaw5D4/Y9+olZvII/kh5W8RGn4JT9wrOz/qwtdnYXbYxmjp4i20mLzXWqs9ewVUKIo8FZ+7mXP+sKYKk+e754tLw==

Token been received: cbczbin8lo9+aivmbegaj1k5iyrj3fbokj/wsh0nzzuggusgwofanovomp8y5b/481ap/mpnusv1ylmxq1zfqmi4s/7xymtrn3iesiviewmuxwpf8o41y1pfq1tf8gaaw5d4/y9+olzvii/kh5w8rgn4jt9wroz/qwtdnyxbyxmjp4i20mlzxwqs9ewvukio8fz+7mxp+skykk+e754tlw==

As you can see, the only difference is that for some reason, there are Upper case letters when its been generated and they are been changed to lower case, probably caused by the HttpUtility.UrlEncode / HttpUtility.UrlDencode actions?

Forgot Password:

string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = HttpUtility.UrlEncode(code) }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Reset Password", string.Format("Please reset your password by clicking <a href='{0}'>here</a>", callbackUrl));

Reset Password

var code = HttpUtility.UrlDecode(model.Code);
var result = await UserManager.ResetPasswordAsync(user.Id, code, model.Password);

Any idea what is causing this?

Thanks

Upvotes: 1

Views: 1677

Answers (1)

Lasse Holm
Lasse Holm

Reputation: 255

I tried using encode/decode on a similar project of my own and the token came back into the controller as it was supposed to. So it is not producing the same "error" in my test.

With that said, you don't need to encode the token yourself, asp.net will encode the token string for you and decode it as well when it is received again, via the callbackurl. Just use the token directly:

var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

On the receiving end, don't decode it either. (skip this line) var code = HttpUtility.UrlDecode(model.Code);

Just pass model.Code directly into the UserManager method like so and it should work just fine. asp.net will deal with the encodings for you.

var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);

Example:

Original Token oFO0xxL7tLoW7Rfz1Yh2Bblim4x2Yn+6O7FXqwz7NPyRyr80EA9LNjsv+BdCDsTHnJx9nkOpnb+vcoEVczZmL2qnqBxAYQQoCnsgobbQVFEHkoAJi0mhDb5stDIP/XytN8qu5d9EUIOUL5IT+9snciG4SQNSp4/x8T5m1wrLmblEyuvH8/VAwX1S5V+cJpkK8fGSmHunzziwamxt1ERB7A==

Url.Action will encode to this and insert as link in email oFO0xxL7tLoW7Rfz1Yh2Bblim4x2Yn%2B6O7FXqwz7NPyRyr80EA9LNjsv%2BBdCDsTHnJx9nkOpnb%2BvcoEVczZmL2qnqBxAYQQoCnsgobbQVFEHkoAJi0mhDb5stDIP%2FXytN8qu5d9EUIOUL5IT%2B9snciG4SQNSp4%2Fx8T5m1wrLmblEyuvH8%2FVAwX1S5V%2BcJpkK8fGSmHunzziwamxt1ERB7A%3D%3D

Difference + / and == will be incoded as %2B(+) %2F(/) and %3D(=)

Decoded by asp.net before passed to controller oFO0xxL7tLoW7Rfz1Yh2Bblim4x2Yn+6O7FXqwz7NPyRyr80EA9LNjsv+BdCDsTHnJx9nkOpnb+vcoEVczZmL2qnqBxAYQQoCnsgobbQVFEHkoAJi0mhDb5stDIP/XytN8qu5d9EUIOUL5IT+9snciG4SQNSp4/x8T5m1wrLmblEyuvH8/VAwX1S5V+cJpkK8fGSmHunzziwamxt1ERB7A==

Same as the original token.

Upvotes: 1

Related Questions