ServiceStack框架下Token过期异常未触发401错误码如何解决
问题原因
你配置的全局未捕获异常处理器存在两处核心错误:
- 调用
res.EndRequest()时传入了skipHeaders: true参数,该参数会让ServiceStack跳过将响应头(包含状态码)写入响应流的逻辑,你之前设置的401状态码根本不会发送给前端。 - 异常类型判断逻辑存在缺陷:使用
ex.GetType() == typeof(TokenException)只能匹配完全是TokenException类型的异常,如果抛出的是TokenException的子类,该判断会失效,建议使用is关键字做类型判断。
另外你写入响应体和设置状态码的顺序也不合理,应该先设置状态码和响应头,再写入响应内容,避免状态码未被正确关联到响应。
修复方案
将你的全局异常处理器修改为如下代码即可:
this.UncaughtExceptionHandlers.Add((req, res, operationName, ex) => { Log.Error(ex); // 优先处理异常类型,设置对应状态码和响应头 if (ex is TokenException) { res.StatusCode = 401; // 可选:添加符合OAuth2规范的WWW-Authenticate头,方便前端统一处理认证错误 res.AddHeader("WWW-Authenticate", @"Bearer error=""invalid_token"", error_description=""Token已过期"""); } // 写入错误响应体 res.WriteErrorBody(ex); // 关闭请求时禁止跳过响应头写入 res.EndRequest(skipHeaders: false); });
补充说明
你提到部分登录过期场景可以正常触发前端跳转逻辑,是因为这些场景的异常在ServiceStack内置的认证流程中就被处理了,没有走到你自定义的全局未捕获异常处理器,走的是框架默认的401返回逻辑,因此状态码正常。只有未被框架内置流程捕获、最终落到你自定义处理器的异常才会出现状态码丢失的问题。
内容的提问来源于stack exchange,提问作者Guerrilla
相关产品推荐
相关产品推荐

