I\'m using Asp.Net-Identity-2 and I\'m trying to verify email verification code using the below method. But I am getting an \"Invalid Token\"
Here I've the same problem but after a lot of time I found that in my case the invalid token error was raised by the fact that my custom Account class has the Id property re-declared and overridden.
Like that:
public class Account : IdentityUser
{
[ScaffoldColumn(false)]
public override string Id { get; set; }
//Other properties ....
}
So to fix it I've just removed that property and generated again the database schema just to be sure.
Removing this solves the problem.
My issue was that I was missing a <input asp-for="Input.Code" type="hidden" />
control in my Reset Password form
<form role="form" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<input asp-for="Input.Code" type="hidden" />
I was getting the "Invalid Token" error even with code like this:
var emailCode = UserManager.GenerateEmailConfirmationToken(id);
var result = UserManager.ConfirmEmail(id, emailCode);
In my case the problem turned out to be that I was creating the user manually and adding him to the database without using the UserManager.Create(...)
method. The user existed in the database but without a security stamp.
It's interesting that the GenerateEmailConfirmationToken
returned a token without complaining about the lack of security stamp, but that token could never be validated.
My problem was that there was a typo in the email containing the ConfirmationToken:
<p>Please confirm your account by <a href=@ViewBag.CallbackUrl'>clicking here</a>.</p>
This meant the extra apostrophe was appended to the end of the ConfirmationToken.
D'oh!
Related to chenny's 3. Different instances of token providers .
In my case I was passing IDataProtectionProvider.Create
a new guid every time it got called, which prevented existing codes from being recognized in subsequent web api calls (each request creates its own user manager).
Making the string static solved it for me.
private static string m_tokenProviderId = "MyApp_" + Guid.NewGuid().ToString();
...
manager.UserTokenProvider =
new DataProtectorTokenProvider<User>(
dataProtectionProvider.Create(new string[1] { m_tokenProviderId } ))
{
TokenLifespan = TimeSpan.FromMinutes(accessTokenLifespan)
};
In case anyone runs into this, it turns out that the token was not URL-friendly, and so I had to wrap it in a HttpUtility.UrlEncode() like so:
var callback = Url.Content($"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}/reset-password?token={HttpUtility.UrlEncode(token)}&email={user.Email}");