通过 GraphQL 应用从 REST api 调用返回的 cookie

问题描述

在实现 auth GraphQL 模块时,解析器通过 RESTDataSource 调用外部 API。

async logout() {
 return await this.post('/logout',{ credentials: 'include' })
}

这将返回一个空的主体对象(预期)和包含 * Set-Cookie: access_token=; Path=/; Expires=Thu,01 Jan 1970 00:00:00 GMT 的标题

预期的结果是从浏览器中删除了 access_token cookie。如果使用 fetch 直接调用它,那么它会发生,但通过 GraphQL 调用时不会发生。

这里是设置:

# Resolver
Mutation: {
    logout: async (_parent,_args,context) => {
      const api = context.injector.get(UserAPI);
      const response = await api.logout();
      return response;
    },},

和服务器...

# Apollo Server
function apolloGraphqlServer(app: Express) {
  const server = new ApolloServer({
    schema,context: ({ req }): { token: string } => {
      return {
        token: req.headers.authorization,};
    },introspection: true,});

  server.applyMiddleware({ app });
}

和客户(在 Express 上)

const apolloClient = new ApolloClient({
      cache: new InMemoryCache(),link: new SchemaLink({
        schema,context: {
          session: req,token: authCookie ? `Bearer ${authCookie}` : null,}),credentials: 'include',ssrMode: true,});

如何根据响应删除 cookie

解决方法

通过将响应传递到上下文中解决了这个问题...

const server = new ApolloServer({
    schema,context: ({ req,res }): { token: string; res: Response } => {
      return {
        token: req.headers.authorization,res,};
    },});

然后在数据源中,拦截收到的响应并设置标头(如果可用)。

# datasource

didReceiveResponse(response: Response,request: Request) {
    if (response.headers.get('set-cookie')) {
      this.context.res.set('set-cookie',response.headers.get('set-cookie'));
    }

    return super.didReceiveResponse(response,request);
  }

不确定这是否是最优雅的解决方案,但目前有效

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...