Apollo Server读取req.headers.authorization报invalid token问题
问题排查与解决方案
问题1:运行查询前提示无法连接服务器、无法内省端点
触发原因
- Apollo Server默认在
NODE_ENV=production环境下关闭内省功能 - 服务端CORS配置未允许Apollo Sandbox的访问源,跨域请求被浏览器拦截,因此服务端终端无错误日志
修复方法
修改Apollo Server初始化配置,开启内省并放开CORS限制:
如果使用@apollo/server v4+版本:
// index.js中调整配置 const server = new ApolloServer({ typeDefs, resolvers, // 强制开启内省 introspection: true, }); // 启动时配置CORS const { url } = await startStandaloneServer(server, { listen: { port: 4000 }, cors: { origin: "*", // 开发环境可直接用通配符,生产环境替换为你的前端域名 credentials: true, }, });
如果使用apollo-server-express版本:
const server = new ApolloServer({ typeDefs, resolvers, introspection: true, }); await server.start(); app.use(cors({ origin: "*" })); app.use(express.json()); server.applyMiddleware({ app });
问题2:运行查询提示Context creation failed: invalid token,硬编码令牌正常
触发原因
标准Authorization请求头的格式为Bearer <令牌内容>,你直接将带Bearer 前缀的完整字符串传入JWT校验接口导致校验失败,硬编码时仅复制了纯令牌内容因此运行正常。
修复方法
修改context逻辑,先提取纯令牌内容再做校验:
// context逻辑调整 const context = async ({ req }) => { const auth = req.headers.authorization; // 先校验头格式是否符合要求 if (!auth || !auth.startsWith('Bearer ')) { return { user: null }; // 如果接口需要强制登录,可在此处直接抛出鉴权错误 } // 提取前缀后的纯令牌内容 const token = auth.split(' ')[1]; try { const user = jwt.verify(token, process.env.JWT_SECRET); return { user }; } catch (err) { throw new Error('Context creation failed: invalid token'); } }
额外排查点
- 确认JWT校验密钥和login接口生成令牌时使用的密钥完全一致,无多余空格、大小写错误
- 确认Apollo Sandbox中填写的请求头格式正确:键为
Authorization,值为Bearer <你的令牌内容>,注意Bearer和令牌之间有1个英文空格 - 可以调用
jwt.decode(token)打印解码后的payload,确认令牌本身格式、有效期正常
内容的提问来源于stack exchange,提问作者entesar
相关产品推荐
相关产品推荐

