使用GraphQL Playground添加授权Token时触发Server Error无法连接服务器
问题解决方案:GraphQL添加授权Token后提示Server cannot be reached
核心原因排查与解决方法
- 原因1:
getUserId工具函数未做异常捕获
你当前的context逻辑只要检测到Authorization头就会直接调用getUserId,如果该函数内JWT验证失败、Token格式不符合预期就会抛出未捕获的错误,直接中断请求返回异常,前端就会提示服务器不可达。
修复方法:给getUserId调用添加异常捕获:
context:({ req }) => { let userId = null if (req?.headers?.authorization) { try { userId = getUserId(req) } catch (err) { // 可按需打印错误日志排查问题 console.log('Token验证失败:', err) userId = null } } return { ...req, prisma, userId }; }
- 原因2:CORS配置未允许Authorization头跨域
如果你是跨域请求(比如前端运行在localhost:3000,服务端运行在localhost:4000),带自定义头Authorization的请求会先发送OPTIONS预检请求,默认的Apollo Server CORS配置没有允许该头,会直接拦截预检请求,导致前端提示无法连接服务器。
修复方法:在ApolloServer配置中添加CORS规则:
const server = new ApolloServer({ typeDefs: fs.readFileSync( path.join(__dirname, 'schema.graphql'), 'utf-8' ), resolvers, // 新增cors配置 cors: { origin: "*", // 生产环境请替换为你的前端实际地址 credentials: true, allowedHeaders: ["Content-Type", "Authorization"] }, context:({ req }) => { // 上述修改后的context逻辑 } });
- 原因3:Authorization头格式不符合预期
通常JWT授权头的标准格式是Bearer <你的Token字符串>,如果你的getUserId函数中默认拆分了Bearer前缀,而你传头的时候没有加该前缀,就会导致字符串拆分报错,验证逻辑崩溃。
修复方法:传请求头时检查格式,头的key为Authorization,值为Bearer 你的Token字符串格式即可。 - 原因4:请求未携带加密算法匹配的有效Token
如果你生成Token用的JWT密钥和getUserId中验证用的密钥不一致,或者Token已经过期,也会导致验证抛出错误,可以先打印getUserId的报错信息确认具体问题。
内容的提问来源于stack exchange,提问作者Karan Sharma
相关产品推荐
相关产品推荐

