ServiceStack JWT令牌自动刷新失效问题排查与解决
JWT令牌过期后无法自动刷新的问题及解决
配置信息
我配置API服务以支持JWT令牌的代码如下:
appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(), [ new JwtAuthProvider(appSettings) { UseTokenCookie = true, ExpireTokensIn = TimeSpan.FromMinutes(1), ExpireRefreshTokensIn = TimeSpan.FromDays(1) }, new CredentialsAuthProvider(appSettings) { }, new GoogleAuthProvider(appSettings) { } ]) { IncludeDefaultLogin = false, ValidateRedirectLinks = AuthFeature.AllowAllRedirects });
- ServiceStack API部署在
https://localhost:5555 - WASM Blazor客户端部署在
https://localhost:5551
初始问题
Bearer Token过期后,浏览器不再在HTTP请求中携带ss-tok Cookie(但ss-reftok仍会被包含),导致API请求返回401响应。请问是否需要在客户端或服务器端添加自定义处理来刷新Bearer Token?
2024年1月21日更新:异常排查
在API服务器尝试刷新令牌时,出现以下异常:
fail: ServiceStack.ServiceStackHost[0] The input string 'w9YFY55pKWxSNbmwb7HE' was not in a correct format. System.FormatException: The input string 'w9YFY55pKWxSNbmwb7HE' was not in a correct format. at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value) at System.Int32.Parse(String s) at ServiceStack.Auth.OrmLiteAuthRepositoryBase`2.<>c__DisplayClass87_0.<<GetUserAuthAsync>b__0>d.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/Auth/OrmLiteAuthRepositoryAsync.cs:line 325 --- End of stack trace from previous location --- at ServiceStack.Auth.OrmLiteAuthRepository`2.ExecAsync[T](Func`2 fn) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/Auth/OrmLiteAuthRepositoryAsync.cs:line 33 at ServiceStack.Auth.OrmLiteAuthRepositoryBase`2.GetUserAuthAsync(String userAuthId, CancellationToken token) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/Auth/OrmLiteAuthRepositoryAsync.cs:line 324 at ServiceStack.RequestExtensions.GetSessionFromSourceAsync(IRequest request, String userAuthId, Func`3 validator, CancellationToken token) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/RequestExtensions.cs:line 317 at ServiceStack.RequestExtensions.GetSessionFromSourceAsync(IRequest request, String userAuthId, Func`3 validator, CancellationToken token) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/RequestExtensions.cs:line 332 at ServiceStack.Auth.JwtAuthProvider.CreateAccessTokenFromRefreshToken(String refreshToken, IRequest req) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Auth/JwtAuthProvider.cs:line 430 at ServiceStack.Auth.GetAccessTokenService.Any(GetAccessToken request) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Auth/JwtAuthProvider.cs:line 505 at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req, Object instance, TRequest requestDto) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Host/ServiceRunner.cs:line 149
调试后发现,CreateAccessTokenFromRefreshToken方法通过var userId = jwtPayload["sub"];获取userId时,该值并非整数类型,说明刷新令牌创建时的sub字段值为非整数。
解决方法
通过在CustomUserSession.OnAuthenticatedAsync中设置session.UserAuthId = CustomUserSession.Id,解决了该问题。现在刷新令牌的sub字段拥有预期的整数值,功能恢复正常。推测该问题可能与使用Google Auth Provider进行身份认证有关。
内容的提问来源于stack exchange,提问作者marcinn
相关产品推荐
相关产品推荐

