【问题标题】:Unable to set Auth Headers using Apollo Client 3 and setContext (apollo-link-context)无法使用 Apollo Client 3 和 setContext (apollo-link-context) 设置 Auth Headers
【发布时间】:2020-09-09 02:11:59
【问题描述】:

所以我试图将授权标头传递给 Apollo Client 3 以访问数据库。在当前文档中推荐的方法是创建一个 HttpLink 对象

const httpLink = new HttpLink({
  uri: "************************",
  fetch
});

然后使用 setContext 方法(我认为来自 'http-link-context'):

const authLink = setContext((_, { headers, ...context }) => {
  const token = localStorage.getItem("userToken");
  return {
    headers: {
      ...headers,
      ...(token
        ? { Authorization: `Bearer ${token}` }
        : `Bearer *************************`)
    },
    ...context
  };
});

然后将对象移植到一起并将它们作为“链接”对象传递给新的 ApolloClient :

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink)
});

不幸的是,当我这样做时,我收到一条错误消息

Uncaught (in promise) Error: GraphQL error: Missing authorization header.

当我检查我的请求标头时,我看不到授权标头。

还有其他人能够成功启动并运行它吗?

【问题讨论】:

    标签: reactjs graphql apollo apollo-client


    【解决方案1】:

    非常烦人的是,他们在 Apollo 的文档中给出的示例没有显示 setContext 的导入,因此在使用最新版本时,不应从“http-link-context”导入所需的包,而是从“@apollo/link-context”导入版本的阿波罗(或阿波罗 3,无论如何)。使用当前的包可以正常工作。

    【讨论】:

      【解决方案2】:

      我认为他们更新了包含 setContext 的文档:

          import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
          import { setContext } from '@apollo/client/link/context';
          
          const httpLink = createHttpLink({
            uri: '/graphql',
          });
          
          const authLink = setContext((_, { headers }) => {
            // get the authentication token from local storage if it exists
            const token = localStorage.getItem('token');
            // return the headers to the context so httpLink can read them
            return {
              headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : "",
              }
            }
          });
          
          const client = new ApolloClient({
            link: authLink.concat(httpLink),
            cache: new InMemoryCache()
          });
      

      您不再需要单独安装 @apollo/link-context,所有内容现在都与 apollo 3.0 捆绑在一起。 【参考】:https://www.apollographql.com/docs/react/networking/authentication

      【讨论】:

      • 首先,没有人在本地存储中保存令牌。其次,来自setContextheaders 是空的。你在发布之前尝试过吗?
      • 不知道标头是否为空,但授权标头设置正确。为我工作。应该被接受的答案。
      • 对我不起作用,似乎 apollo 完全忽略了 authlink,甚至不运行它。当我将 console.logs 放在 setContext 函数中时,它不会运行。
      【解决方案3】:

      第一个 apollo-link-context 现在是 @apollo/client/link/context

      第二个:你可以在 apolloclient 中使用标头

      const client = new ApolloClient({
          cache,
        uri: 'http://localhost:4000/graphql',
        headers: {
          authorization: localStorage.getItem('token') || '',
          'client-name': 'Space Explorer [web]',
          'client-version': '1.0.0',
        },
        // or authLink because its return Headers
        ...authLink
      });
      

      【讨论】:

      • 如果令牌保存在 cookie 中会怎样?
      • @AlanYong 然后实现是一样的,只是从cookie中获取。但在这两种情况下,将其存储在 cookie 或本地/会话存储中是个坏主意,因为它们不安全。攻击者可以得到你的令牌,然后对你的帐户为所欲为。
      • @martin.malek 你建议在哪里保存令牌?
      猜你喜欢
      • 2020-10-14
      • 2020-05-20
      • 2021-07-31
      • 2018-09-05
      • 2021-01-15
      • 2019-03-08
      • 2019-12-01
      • 2020-12-06
      • 2021-12-04
      相关资源
      最近更新 更多