Spring Boot OAuth2 Client调用接口遇401,浏览器访问却正常?
这种情况我之前踩过好几次坑,大概率是请求的细节和浏览器自动处理的部分有差异,给你列几个最常见的排查方向:
Token传递格式错误
很多时候是Authorization头的格式出了问题:如果用的是Bearer Token,必须写成Bearer <你的token>,中间的空格绝对不能少!不少人会不小心写成Bearer<token>或者直接把token丢进去,服务器根本识别不了。
举个axios的正确示例:axios.get('/your-api-endpoint', { headers: { 'Authorization': 'Bearer ' + yourToken // 注意这里的空格 } })另外也可以检查下,是不是浏览器里是通过URL参数传token(比如
?auth=xxx),但代码里误用了请求头,或者反过来。Cookie未携带
有些API会依赖会话Cookie,浏览器访问时会自动带上当前域名的Cookie,但代码里的请求默认不会携带。如果是这种情况,需要在请求里开启携带Cookie的配置:- axios:设置
withCredentials: true - fetch:添加
credentials: 'include'参数
- axios:设置
请求头缺失关键字段
浏览器会自动添加一些请求头(比如User-Agent、Accept),部分服务器会校验这些字段是否存在。你可以用浏览器开发者工具的Network面板,把浏览器请求的头信息和代码请求的头信息做对比,把缺失的字段补上试试。Token编码/转义问题
复制到浏览器的token是原始格式,但代码里可能对token做了不必要的URL编码或者转义,导致服务器无法解析。检查代码里的token字符串和浏览器里的是否完全一致,有没有多余的%20或者转义符。跨域预检请求失败
如果是前端项目的跨域请求,浏览器会先发送OPTIONS预检请求。如果服务器没有正确处理OPTIONS请求(比如没有返回允许的头、方法),后续的GET请求也可能返回401。可以看看浏览器控制台有没有跨域相关的报错信息。
先从检查Authorization头的格式开始吧,这是最容易踩的坑。如果还是不行,把两个请求的完整信息(头、参数、甚至请求方式)对比一遍,差异点基本就是问题所在。
内容的提问来源于stack exchange,提问作者Phil Palmiero

