文章内容
2019/9/8 15:20:36,作 者: 黄兵
Identity _userManager.ConfirmEmailAsync “Invalid Token” error
最近在使用IdentityServer4的时候,使用的是Identity API实现注册功能,但是在邮箱验证的时候,出现如下错误:Invalid Token
。
具体代码如下:
确认电子邮件具体代码如下:
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
评论列表