graphql-shield配置allow规则后允许的Mutation仍返回Not Authorised问题求助
问题修复方案
1. 先开启graphql-shield调试配置定位真实错误
graphql-shield默认会将resolver抛出的所有非权限类错误统一替换为Not Authorised!返回,会掩盖resolver本身的逻辑错误、参数错误等真实问题,同时默认关闭调试日志。
修改权限配置代码,添加调试参数:
import { shield, allow } from "graphql-shield"; const permissions = shield({ Query: { users: allow, }, Mutation: { login: allow, }, }, { debug: true, // 服务端控制台会打印完整错误栈 allowExternalErrors: true, // resolver自身的错误会透传给客户端,不会被替换为权限错误 }); export default permissions;
修改后重新调用login接口,就能看到真实的报错原因。
2. 排查resolver本身逻辑问题
暂时注释掉权限中间件,直接调用login接口确认是否能正常返回:
// 服务端代码临时修改 const server = new ApolloServer({ // 注释掉权限中间件先验证resolver schema: makeExecutableSchema({ typeDefs, resolvers: mockResolver }), // 其余配置不变 });
如果注释后调用login依然报错,说明是resolver本身的逻辑问题(比如入参校验失败、mock数据格式错误等),和权限配置无关。
3. 排查express全局中间件拦截问题
GraphQL的Query请求默认可以用GET方式提交,而Mutation必须用POST方式提交。如果你在express层面配置了全局的JWT校验中间件,拦截了所有POST请求,就会出现Query放行正常、Mutation全部被拦截的问题。
检查是否有类似如下的全局中间件配置,如有需要移除,JWT解析逻辑应该放到Apollo的context中处理,不要在express层全局拦截:
// 错误示例:全局拦截所有请求校验JWT,会导致未登录的POST请求直接被拦截 app.use((req, res, next) => { const token = req.headers.authorization?.split(' ')[1] if (!token) return res.status(401).send('Unauthorized') // 校验逻辑... next() })
4. 排查字段级权限配置
如果你还配置了返回类型的字段级权限规则,比如LoginResponse的token字段配置了需要鉴权,哪怕Mutation级的login配置了allow,返回结果时触发字段权限校验也会报错。检查权限配置中是否有针对返回类型的额外规则,按需放行即可。
内容的提问来源于stack exchange,提问作者Jakub Jaroš
相关产品推荐
相关产品推荐

