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

Posted

技术标签:

【中文标题】通过 GraphQL 应用从 REST api 调用返回的 cookie【英文标题】:Applying cookie returned from REST api call via GraphQL 【发布时间】:2021-08-26 00:17:27 【问题描述】:

在实现 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',
      s-s-rMode: true,
    );

如何根据响应删除 cookie

【问题讨论】:

【参考方案1】:

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

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);
  

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

【讨论】:

以上是关于通过 GraphQL 应用从 REST api 调用返回的 cookie的主要内容,如果未能解决你的问题,请参考以下文章

是否可以通过 GraphQL/REST 后端共享 3rd 方 API websocket/实时连接?

使用 REST 包装 GraphQL 从 NestJS 提供 GraphQL 和 REST API

为什么说GraphQL可以取代REST API?

在 REST API 中使用 GraphQL 进行数据查询

GraphQL 与 REST API

使用 GraphQL 封装 REST API / 仅使用 GraphQL