使用 graphql-shield 的 Apollo Server Federation

Apollo Server Federation with graphql-shield

我正在使用 graphql-shield 来保护 subgraph

const isAuthenticated = rule({ cache: 'contextual' })(async (parent, args, ctx, info) => {
  return ctx.isAuthenticated
})

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

const server = new ApolloServer({
    schema: applyMiddleware(buildSubgraphSchema([{ typeDefs, resolvers }]), permissions),
    introspection: global.configuration.ENVIRONMENT === 'development'
})

在我的构建过程中,我正在使用 rover CLI 更新 Apollo Studio 中的supergraph schema

rover subgraph introspect http://localhost/graphql | rover subgraph publish super-graph@development --routing-url http://localhost/graphql --schema - --name persons

rover 更新失败,因为权限屏蔽引发 Not Authorised! 错误。

如何使用 graphql-shield 保护 subgraph 并允许 SubgraphIntrospectQuery 操作?

我了解可以将不记名令牌添加到流动站内省命令:

rover subgraph introspect http://localhost/graphql --header "Authorization: Bearer token"

但是,我无法在构建过程中生成访问令牌。

我能够通过更改我的身份验证范围解决此问题。

而不是验证所有“*”

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

我更改为对单个操作进行身份验证:

const permissions = shield({
  Query: {
    'user': and(isAuthenticated),
    'users': and(isAuthenticated)
    ....
  },
  Mutation: {
    'createUser': and(isAuthenticated),
    'updateUser': and(isAuthenticated)
    ....
  }
})

您可以尝试允许以下分支:

export const permissions = shield({
    Query: {
        _service: allow,
    },
    _Service: {
        sdl: allow
    }
},{
    fallbackRule: deny,
    allowExternalErrors: true,
    ...
});

Apollo 在进行内省时,最初使用的是这两个分支。还要注意“allowExternalErrors”标志。当遇到错误时,graphql-shield 吸收它们,这可以隐藏您试图调试的问题。这 可能 也是一个问题,尽管您的代码在其他方面看起来还不错。

Apollo 也使用“Query._entities”、“Query._service”、“_Entity.*”、“_Service.*”、“_Any.*”,但我还没有发现这是由初始内省使用。

您提到您无法为构建过程生成令牌,但保护这些端点而不是使用允许可能是个好主意。