supertest设置Authorization头无效返回401未授权问题排查
401未授权问题排查与修复
这个问题和supertest的.set()方法本身无关,90%的概率出在Authorization请求头的格式匹配上,具体原因和修复方式如下:
核心诱因
你在测试代码里写的认证头前缀是全小写的bearer:
.set("Authorization",`bearer xxxxxxxx`)
而你路由里用来提取token的getTokenFrom函数,基本都是按标准HTTP认证规范,硬匹配首字母大写的Bearer 前缀的,常规实现长这样:
const getTokenFrom = request => { const authorization = request.get('authorization') // 注意这里判断的是开头为大写Bearer加空格 if (authorization && authorization.startsWith('Bearer ')) { return authorization.replace('Bearer ', '') } return null }
你传小写bearer开头的头时,这个函数根本识别不到,直接返回null,后续jwt验证拿不到有效token,自然返回401。
至于Postman为什么能正常请求——Postman发请求时会自动修正Authorization头的scheme大小写,你在界面里填的token哪怕前缀写小写,它发出去的时候也会自动转成标准的Bearer开头,所以不会触发这个匹配问题。
修复步骤
- 把测试代码里认证头的前缀改成标准大写开头的
Bearer即可:
await api .post("/api/blogs") .send(newBlog) .set("Authorization", `Bearer xxxxxxxx`) // 修正小写bearer为大写Bearer .set("Accept","application/json") .expect(201)
- 如果改完还是报401,可以在路由逻辑最开头加一句
console.log(request.headers.authorization),确认服务端实际收到的头内容:- 如果打印值是undefined,检查测试文件有没有全局配置清空了自定义请求头,或者有没有前置中间件提前改写了header
- 如果能拿到完整头字符串,就检查
getTokenFrom的字符串匹配逻辑是不是和你传的前缀格式一致
测试优化建议
不要把token硬编码在测试用例里,建议在测试套件的beforeEach钩子中先调用登录接口获取当前测试用户的有效token,再传给后续需要认证的请求,避免token过期、硬编码值和实际签发逻辑不匹配的问题。
内容的提问来源于stack exchange,提问作者Julius Goddard
相关产品推荐
相关产品推荐

