“Invalid Token” 在尝试验证 .NET Core 7 应用程序中的帐户时出现。

huangapple go评论78阅读模式
英文:

"Invalid Token" when trying to validate account in .NET Core 7 app

问题

我已经检查了很多关于这个问题的资源,但没有一个适用于我的情况。

我正在使用以下代码生成在电子邮件中发送的令牌:

string token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = $"{_request.Scheme}://{_request.Host}{_request.PathBase}/Authenticate/Security/ConfirmEmail/{user.Id}?token={WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token))}";

当收到电子邮件并点击链接时,会运行以下代码:

var user = await _userManager.FindByIdAsync(userId);

if (user is null)
    return new Result { Success = false, Errors = new Dictionary<string, string[]>() { { "NotFound", new string[] { "Usuario no encontrado " } } };

IdentityResult result = await _userManager.ConfirmEmailAsync(user, Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(token)));

在调试时,我可以检查到由以下代码生成的令牌:

string token = await _userManager.GenerateEmailConfirmationTokenAsync(user);

在运行以下代码后仍然完全相同:

Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(token))

我正在使用相同的开发机器,所以MachineKey不是问题的原因。我正在使用用户时间戳,但它已经正确设置并且从未更改过。

由于生成是由GenerateEmailConfirmationTokenAsync执行的,验证也是由ConfirmEmailAsync执行的,因此密钥的目的相同,并且等于Confirmation

还可以检查什么?

谢谢。

英文:

I have check a lot of resources about this problem but none applies to my case.

I am using this code to generate the token that is sent in the e-mail:

string token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = $&quot;{_request.Scheme}://{_request.Host}{_request.PathBase}/Authenticate/Security/ConfirmEmail/{user.Id}?token={WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token))}&quot;;

When e-mail is received and clicked the link, this code is run:

var user = await _userManager.FindByIdAsync(userId);

if (user is null)
    return new Result { Success = false, Errors = new Dictionary&lt;string, string[]&gt;() { { &quot;NotFound&quot;, new string[] { &quot;Usuario no encontrado &quot; } } } };

IdentityResult result = await _userManager.ConfirmEmailAsync(user, Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(token)));

When debugging, I can check that the token generated by

string token = await _userManager.GenerateEmailConfirmationTokenAsync(user);

is exactly the same after running

Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(token))

I am in the same development machine, so the MachineKey problem is not the cause. I am using user time stamp, but it is correctly set and never changed.

Since generation is made by GenerateEmailConfirmationTokenAsync and validation is made by ConfirmEmailAsync, the purpose of the key is the same, and equal to Confirmation.

What else can I check?

Thanks

答案1

得分: 1

当时发现我正在使用自定义用户存储。当加载ApplicationUser时,我忘记设置安全戳字段。

现在,在加载用户时,我使用以下方法来设置属性:

private static ApplicationUser? GetUserData(Usuario? u)
{
    if (u == null)
        return null;

    return new ApplicationUser
    {
        Id = u.UsuarioId,
        UserName = u.UsuarioLogin,
        FirstName = u.UsuarioNombre,
        LastName = u.UsuarioApellido,
        PhoneNumber = u.UsuarioTelefono,
        PhoneNumberConfirmed = u.UsuarioTelefonoConfirmado,
        Email = u.UsuarioEmail,
        EmailConfirmed = u.UsuarioEmailConfirmado,
        PasswordHash = u.UsuarioPasswordHash,
        SecurityStamp = u.UsuarioSecurityStamp
    };
}

当然,该方法是从自定义用户存储的public async Task<ApplicationUser?> FindByIdAsync(string userId, CancellationToken cancellationToken)方法中调用的。

干杯
Jaime

英文:

It turned out that I am using a custom user store. When I loaded the ApplicationUser, I forgot to set the security stamp field.

Now, when loading the user, I am using this method to set the properties:

    private static ApplicationUser? GetUserData(Usuario? u)
    {
        if (u == null)
            return null;

        return new ApplicationUser
        {
            Id = u.UsuarioId,
            UserName = u.UsuarioLogin,
            FirstName = u.UsuarioNombre,
            LastName = u.UsuarioApellido,
            PhoneNumber = u.UsuarioTelefono,
            PhoneNumberConfirmed = u.UsuarioTelefonoConfirmado,
            Email = u.UsuarioEmail,
            EmailConfirmed = u.UsuarioEmailConfirmado,
            PasswordHash = u.UsuarioPasswordHash,
            SecurityStamp = u.UsuarioSecurityStamp
        };
    }

Of course, the method is called from public async Task&lt;ApplicationUser?&gt; FindByIdAsync(string userId, CancellationToken cancellationToken) of custom user store.

Cheers
Jaime

huangapple
  • 本文由 发表于 2023年6月26日 00:43:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定