You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:05:10