Identity Framework test if confirm email token is expired

后端 未结 3 1512
死守一世寂寞
死守一世寂寞 2021-02-07 05:18

Is it possible to test whether a confirm email token is expired using Identity Framework\'s UserManager? No matter what the error is, from the following:

         


        
3条回答
  •  失恋的感觉
    2021-02-07 05:37

    Here comes an .NET Core 2.1 adaption of the solution provided by @Nkosi :

    ApplicationUser class

    public class ApplicationUser : IdentityUser 
    {
        public string EmailConfirmationToken { get; set; }
        public string ResetPasswordToken { get; set; }
    }
    

    Derived UserManager class

    public class CustomUserManager : UserManager
    {
        public CustomUserManager(IUserStore store, 
            IOptions optionsAccessor, 
            IPasswordHasher passwordHasher, 
            IEnumerable> userValidators, 
            IEnumerable> passwordValidators, 
            ILookupNormalizer keyNormalizer, 
            IdentityErrorDescriber errors, 
            IServiceProvider services, 
            ILogger> logger) 
            : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
        {
    
        }
    
        public override async Task GenerateEmailConfirmationTokenAsync(ApplicationUser user)
        {
            /* NOTE:
                * The default UserTokenProvider generates tokens based on the users's SecurityStamp, so until that changes
                * (like when the user's password changes), the tokens will always be the same, and remain valid. 
                * So if you want to simply invalidate old tokens, just call manager.UpdateSecurityStampAsync().
                */
            //await base.UpdateSecurityStampAsync(userId);
    
            var token = await base.GenerateEmailConfirmationTokenAsync(user);
            if (!string.IsNullOrEmpty(token))
            {
                user.EmailConfirmationToken = token; //<<< Last issued token
                //Note: If a token is generated then the current email is no longer confirmed.
                user.EmailConfirmed = false;
                await UpdateAsync(user);
            }
            return token;
        }
    
        public override async Task ConfirmEmailAsync(ApplicationUser user, string token)
        {
            if (user == null)
            {
                return IdentityResult.Failed(new IdentityError {Description = "User not found."});
            }
            var result = await base.ConfirmEmailAsync(user, token);
            if (result.Succeeded)
            {
                user.EmailConfirmationToken = null;
                return await UpdateAsync(user);
            }
            else if (user.EmailConfirmationToken == token)
            {
                //Previously Issued Token expired
                result = IdentityResult.Failed(new IdentityError { Description = "Expired token." });
            }
            return result;
        }
    
    }
    

    UserManager Extension

    public static class ApplicationUserManagerExtension
    {
        public static Task FindIdByEmailConfirmationTokenAsync(this UserManager manager, string confirmationToken)
        {
            string result = null;
    
            ApplicationUser user = manager.Users
                .SingleOrDefault(u => u.EmailConfirmationToken != null && u.EmailConfirmationToken == confirmationToken);
    
            if (user != null)
            {
                result = user.Id;
            }
            return Task.FromResult(result);
        }
    }
    

    Update: The CustomUserManager has to be added to services in Startup.cs in ConfigureServices Method.

    services.AddTransient();
    

    Without this, DependencyInjection fails.

提交回复
热议问题