Identity Framework test if confirm email token is expired

后端 未结 3 1573
死守一世寂寞
死守一世寂寞 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:30

    I get around this by keeping/storing a copy of the generated token

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

    and associating it with the user in derived UserManager.

    public override async System.Threading.Tasks.Task GenerateEmailConfirmationTokenAsync(string userId) {
        /* 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(userId);
        if (!string.IsNullOrEmpty(token)) {
            var user = await FindByIdAsync(userId);
            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;
    }
    

    When the token is provided for confirmation, a search for the user via the token is done.

    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);
        }
    }
    

    If the token matches a known user that indicates that it was a validly issued token.

    Will then attempt to confirm token with User manager.

    If confirmation fails then token has expired and an appropriate action is taken.

    Else if the token confirmed, it is removed from associated user and thus invalidating the reuse of that token.

    public override async System.Threading.Tasks.Task ConfirmEmailAsync(string userId, string token) {
        var user = await FindByIdAsync(userId);
        if (user == null) {
            return IdentityResult.Failed("User Id Not Found");
        }
        var result = await base.ConfirmEmailAsync(userId, token);
        if (result.Succeeded) {
            user.EmailConfirmationToken = null;
            return await UpdateAsync(user);
        } else if (user.EmailConfirmationToken == token) {
            //Previously Issued Token expired
            result = IdentityResult.Failed("Expired Token");
        }
        return result;
    }
    

    A similar approach was implemented for password reset as well.

提交回复
热议问题