Apollo GraphQL 动态认证子图

Ran*_*dom 5 apollo graphql graphql-js apollo-server apollo-federation

我正在构建一个带有联合模式的 Apollo 网关 - 并且我有许多子图 - 每个子图都有自己的身份验证令牌(例如许多 REST API,每个用户在每个 REST API 的数据库中保存了自己的令牌)。

我正在为网关中的每个用户的每个 REST API 获取令牌,以减少每个子图的过载并检查网关级别的权限,但我正在努力解决如何将凭据从网关传递到每个子图的问题。

我遇到了这个答案,但是,在这里他正在构建自己serviceList,而我正在使用 Apollo Federation - 并且网关对象无法访问,serviceMap因为它在 Typescript 定义下是私有的 - 这是一种非常黑客的方式实现它的方法:

class RequestHander extends RemoteGraphQLDataSource {
    willSendRequest({ request }: { request: GraphQLRequest }) {
        // if request.http.url matches url of a service which you
        // use, add api-key to headers, e.g.
        if (request.http.url === 'http://localhost:3001') {
            request.http.headers.set('api-key', <API_KEY>)
        }
    }
}

const main = () => {
    const gateway = new ApolloGateway({
        buildService: ({ url }) => new RequestHander({ url }),
        serviceList: [
            { name: 'service1', url: 'http://localhost:3001' },
            { name: 'service2', url: 'http://localhost:3002' },
        ],
    })

    const server = new ApolloServer({ gateway })

    void server.listen({ port: 3000 }).then(({ url }) => {
        logger.info(`Apollo Gateway ready at ${url}`)
    })
}
Run Code Online (Sandbox Code Playgroud)

有什么最佳实践或更好的方法来制作动态验证的子图?

Ran*_*dom 0

我目前的解决方案确实是访问Gateway下的私有serviceMap入口,如下:

for (const [serviceName, dataSource] of Object.entries((<any>gateway).serviceMap)) {
    if ((<any>dataSource).url == request.http?.url) { 
      ... 
    }
}
.
Run Code Online (Sandbox Code Playgroud)