3

When I'm trying to reset a password, I'm using userManager.VerifyUserTokenAsync(user, tokenProvider, purpose, token) but it always returns false. My suspicion is that the purpose field is wrong but I'm not sure what should actually go there. My question is, how do I get the purpose field? From some examples I've seen, people are setting it "ResetPassword". Is this correct or am I missing something?

Thanks!

Startup.cs

services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
            {
                options.Password.RequiredLength = 6;
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.User.RequireUniqueEmail = true;
                options.SignIn.RequireConfirmedAccount = true;
                options.SignIn.RequireConfirmedEmail = true;
                options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
                options.Tokens.EmailConfirmationTokenProvider = "emailconfirmation";
            })
             .AddEntityFrameworkStores<VisualDbContext>()
             .AddDefaultTokenProviders()
             .AddTokenProvider<EmailConfirmationTokenProvider<ApplicationUser>>("emailconfirmation");

            services.Configure<DataProtectionTokenProviderOptions>(opt =>
                opt.TokenLifespan = TimeSpan.FromHours(2));

            services.Configure<EmailConfirmationTokenProviderOptions>(opt =>
                opt.TokenLifespan = TimeSpan.FromDays(3));
// Forgot Password
    var token = await _userManager.GeneratePasswordResetTokenAsync(user);
    var encodedToken = HttpUtility.UrlEncode(token);
//Verify Reset Token
    var purpose = "WHAT GOES HERE?";
    var result = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultEmailProvider, purpose, token);

Thanks

roonz11
  • 795
  • 1
  • 13
  • 24

1 Answers1

4

There are 3 "token purpose" constants defined for you to use on the User Manager class, as you can see in the UserManager source code.

In your specific use case, you would want to do this:

//Replace TUser with your user type
var purpose = UserManager<TUser>.ResetPasswordTokenPurpose;
var result = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultEmailProvider, purpose, token);

Or you could do this:

var purpose = UserManager<object>.ResetPasswordTokenPurpose;

Unfortunately, because the UserManager class is generic, you have to write somewhat ugly code to access the constants. Maybe in the future, Microsoft could add a non generic parent class as described here, to make accessing the purpose constants more elegant.

pistol-pete
  • 1,213
  • 17
  • 13