Apollo GraphQL 的动态标头(中间件之外)

Posted

技术标签:

【中文标题】Apollo GraphQL 的动态标头(中间件之外)【英文标题】:Dynamic headers for Apollo GraphQL (outside of middleware 【发布时间】:2019-11-13 04:46:50 【问题描述】:

由于 Apollo 链接中间件似乎是在构造时定义的,我想知道如何传递动态标头。

具体来说,我有一个身份验证系统,其中 signIn 和 signUp 不需要令牌的标头。但是任何经过身份验证的 API 调用都单独依赖于用户上下文的令牌。因此,如果存在令牌(localStorage.getItem('token');),它会使用该令牌进行身份验证。否则,它使用从 signUp/signIn 传回的令牌进行身份验证。

所以我想知道如何将标头动态传递给查询/变异组件。

<Query query=query>
    ( loading, error, data ) => 
        if (loading) return "Loading...";
        if (error) return `Error! $error.message`;
        return (
            <select className="CompanySelector">
                data.companies.map(companies => (
                    <option className="CompanySelection" key=companies.id value=companies.name>
                        companies.name
                    </option>
                ))
            </select>
        );
    
</Query>

我尝试包装查询,但 Apollo 似乎没有将 graphql 函数作为参数。

export const wrap = (query, token) => 
    return graphql(query, 
        options: 
            context: 
                headers: 
                    'x-token': token
                
            
        
    )
;

这是查询:

export const COMPANIES = gql`
    query companies
        companies
            name, id
        
    
`;

【问题讨论】:

【参考方案1】:

Query 支持 context 属性,因此您可以使用它来配置特定于查询的授权:

<Query
  context=
    headers: 
      'x-token': localStorage.getItem('token')
    
  
>
  ( loading, data ) => // render the stuff
</Query>

并通过 Apollo 客户端的 fetch 函数中的 opt 处理自定义标头:

const httpLink = new HttpLink(
    # ...,
    fetch: (uri, opts) =>
      window.fetch(uri, 
        ...opts,
        headers: 
          'x-token': opts.headers && opts.headers['x-token'] || getTokenDefaultWay()
        
      )
  )
)

【讨论】:

我有类似的要求,我有 setcontext 中间件在施工。但是我必须在没有授权标头的情况下运行几个查询。如何,可以禁用中间件,以便我可以在查询的上下文中传递不同的标头。我尝试在查询中传递不同的标头,但由于中间件配置了授权,我的服务器响应是错误的。

以上是关于Apollo GraphQL 的动态标头(中间件之外)的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL:无法读取 Apollo 客户端中的响应标头

如何使用 apollo graphql 处理授权标头?

如何将标头添加到 ionic 4 / Apollo GraphQL App

Apollo graphql 将标头设置为 authmiddleware 不起作用

Apollo GraphQL 标头在 iOS Swift 中总是失败

是否可以为 Apollo Server 附带的 GraphQL Playground 定义 HTTP 标头?