在哪里可以找到 ASP.NET Identity 2 中生成的 PasswordReset 令牌?

Where to find Generated PasswordReset Tokens in ASP.NET Identity 2?

有什么方法可以在 ASP.NET Identity 2 中查看生成的密码重置令牌?
我的假设是 TokenProvider 中应该有一个字典,它在内存中保存这些标记。

更新:
这里有一个类似的问题ResetPassword Token How and where is it stored?

"Tokens are generated using the SecurityStamp and validating against the SecurityStamp and not storing anywhere in database or local file storage."

但问题仍然是框架如何知道令牌何时过期而不存储它?

正如一位评论者所提到的

"Tokens are generated using the SecurityStamp and validated against the SecurityStamp and not stored anywhere in database or local file storage."

引用自ResetPassword Token How and where is it stored?

以下是我如何能够保留令牌供以后使用。

我假设您使用的是默认项目模板。

ApplicationUser 中创建属性来存储令牌。

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

AspNetUsers table 中创建相应的列。

然后我更新了 ApplicationUserManager class 如下。

    public override async System.Threading.Tasks.Task<string> 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);
        //associate the email token with the user account
        if (!string.IsNullOrEmpty(token)) {
            var x = await FindByIdAsync(userId);
            x.EmailConfirmationToken = token;
            x.EmailConfirmed = false;

            await UpdateAsync(x);
        }

        return token;
    }

    public override async System.Threading.Tasks.Task<string> GeneratePasswordResetTokenAsync(string userId) {
        var token = await base.GeneratePasswordResetTokenAsync(userId);
        if (!string.IsNullOrEmpty(token)) {
            var x = await FindByIdAsync(userId);
            x.ResetPasswordToken = token;
            await UpdateAsync(x);
        }
        return token;
    }

    public override async System.Threading.Tasks.Task<IdentityResult> ConfirmEmailAsync(string userId, string token) {
        var result = await base.ConfirmEmailAsync(userId, token);
        if (result.Succeeded) {
            var x = await FindByIdAsync(userId);
            x.EmailConfirmationToken = null;
            await UpdateAsync(x);
        }
        return result;
    }

    public override async System.Threading.Tasks.Task<IdentityResult> ResetPasswordAsync(string userId, string token, string newPassword) {
        var result = await base.ResetPasswordAsync(userId, token, newPassword);
        if (result.Succeeded) {
            var x = await FindByIdAsync(userId);
            x.ResetPasswordToken = null;
            await UpdateAsync(x);
        }
        return result;
    }

以上更改允许我在会话之间保留令牌。

令牌未存储在内存中,而是根据给定的 SecurityStamp 即时生成。 Token 基本上是一个 Unicode 编码的字符串。

您可以查看 UserManager.csCreateSecurityTokenAsync 方法。

internal async Task<byte[]> CreateSecurityTokenAsync(TUser user)
{
    return Encoding.Unicode.GetBytes(await GetSecurityStampAsync(user));
}