You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用graphql-shield防护Apollo子图时如何放行SubgraphIntrospectQuery

解决方案

你可以通过调整graphql-shield的权限规则,单独放行内省相关的查询操作,无需认证即可访问,两种实现方案如下:

方案1:显式枚举内省字段放行

graphql-shield的规则匹配优先级为「精确字段匹配 > 通配符匹配」,你可以直接对内省需要用到的字段单独设置公开权限:

const isAuthenticated = rule({ cache: 'contextual' })(async (parent, args, ctx, info) => {
  return ctx.isAuthenticated
})
// 新增公开访问规则
const isPublic = rule({ cache: 'contextual' })(async () => true)

const permissions = shield({
  Query: {
    '*': and(isAuthenticated),
    // 放行GraphQL标准内省字段
    __schema: isPublic,
    __type: isPublic,
    // 放行Apollo联邦子图专属内省字段
    _service: isPublic
  },
  Mutation: {
    '*': and(isAuthenticated)
  }
})

方案2:动态识别内省请求放行

如果你不想手动枚举所有内省相关字段,可以新增规则自动识别内省请求直接放行,适配性更强:

const isAuthenticated = rule({ cache: 'contextual' })(async (parent, args, ctx, info) => {
  return ctx.isAuthenticated
})
// 新增内省请求识别规则
const isIntrospectionRequest = rule({ cache: 'contextual' })(async (parent, args, ctx, info) => {
  // 匹配Rover子图内省的固定操作名
  if (info.operation.name?.value === 'SubgraphIntrospectQuery') return true
  // 匹配所有GraphQL标准内省字段(均以__开头)
  if (info.fieldName.startsWith('__')) return true
  // 匹配Apollo联邦子图内省专属字段
  if (info.fieldName === '_service') return true
  return false
})

const permissions = shield({
  Query: {
    '*': and(or(isIntrospectionRequest, isAuthenticated))
  },
  Mutation: {
    '*': and(isAuthenticated)
  }
})

可选优化

如果需要避免公开暴露内省接口,可以在放行规则中增加额外校验逻辑,比如:

  • 仅在非生产环境放行内省请求
  • 校验请求来源IP属于你的构建集群网段

内容的提问来源于stack exchange,提问作者capiono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:15:03