文章内容

2019/9/8 15:20:36,作 者: 黄兵

Identity _userManager.ConfirmEmailAsync “Invalid Token” error

最近在使用IdentityServer4的时候,使用的是Identity API实现注册功能,但是在邮箱验证的时候,出现如下错误:Invalid Token

具体代码如下:

var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.Action(
                action"ConfirmEmail",
                controller"Account",
                valuesnew { userId = user.Idcode = code },
                host:"p.pdflibr.com",
                protocolRequest.Scheme);
            await _emailSender.SendEmailAsync(model.username, "Confirm your email",
        $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

确认电子邮件具体代码如下:

var result = await _userManager.ConfirmEmailAsync(user, code);
return new JsonResult(result.Succeeded ? "ConfirmEmail" : "Error");

在验证的时候始终是Invalid Token错误。

后来在AccountController控制器新建账号的时候,邮箱却是可以验证的。

具体AccountController的写法与上面无异。但是为什么AccountController验证邮箱可以成功API却无法成功呢?

陷入了长长的思考当中。

参考了一些其他人的解决方案,也是无解。

是不是由于编码导致的token不对?

带着这个猜疑,我直接复制未经转码的code,看看能否验证通过,没想到居然验证通过了。

那现在就好办了,只要在验证之前,code解码就可以解决问题了。

具体代码如下:

code = HttpUtility.UrlDecode(code);
var result = await _userManager.ConfirmEmailAsync(user, code);
return new JsonResult(result.Succeeded ? "ConfirmEmail" : "Error");

再次测试终于解决问题。

但是在Angular中使用的时候还是会出现Invalid Token错误。

出现这个问题的原因是:

浏览器会对URI进行编码,导致code的内容改变,出现Invalid Token错误

解决方案:


答案即将揭晓。

对URI参数(code)进行编码,使用base64的编码方式。

在base 64 url​​中编码token,然后在base 64 url​​中对其进行解码。这样,Angular和ASP.NET Core都将检索相同的code。

创建用户发送验证码的代码如下(部分):

// Angular 编码有问题,此处编码URI
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
byte[] tokenGeneratedBytes = Encoding.UTF8.GetBytes(code);
var codeEncoded = WebEncoders.Base64UrlEncode(tokenGeneratedBytes);

通过Base64编码,防止在传输的过程中出现转义。

之后是验证邮件的代码(部分):

 // Angular 编码会出现问题,此处要解码
var codeDecodedBytes = WebEncoders.Base64UrlDecode(code);
var codeDecoded = Encoding.UTF8.GetString(codeDecodedBytes);

var result = await _userManager.ConfirmEmailAsync(user, codeDecoded);

对传输过来的Base64进行解码,恢复原来的code真面目。



参考资料:

1、HttpUtility.UrlDecode Method

2、HttpUtility.UrlEncode Method

3、Asp.NET Identity 2 giving “Invalid Token” error

4、_userManager.ResetPasswordAsync(...) is returning Invalid Token validation message

5、ASP.NET Core Identity invalid token on confirmation email


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - Identity _userManager.ConfirmEmailAsync “Invalid Token” error

分享到:

发表评论

评论列表