【问题标题】:Apollo client + Next.js - Adding Authorization token to client requestApollo 客户端 + Next.js - 向客户端请求添加授权令牌
【发布时间】:2020-01-24 08:04:18
【问题描述】:

目标

我想用访问令牌填充我的 Authorization 标头。我想将该访问令牌存储在 Apollo 缓存中,因为 Auth0 明确声明不要将访问令牌存储在本地存储中(我不知道为什么 Apollo Client docs 似乎认为没关系)。

如果做不到这一点,我想安全地存储我的访问令牌,并能够将其添加到每个 Apollo 客户端对 Apollo 服务器的请求中。

const apolloClient = withApollo(({ctx, headers, initialState}) => {
  const cache = new InMemoryCache();

  // Code here to access local cache.

  return new ApolloClient({

    cache,
    link: new HttpLink({
      uri: <apollo server endpoint>,
      headers: {
        Authorization: `Bearer ${accessToken}`,
        'Access-Control-Allow-Origin': 'http://localhost:3000/',
        ...headers
      },
      credentials: 'include'
    }),
    typeDefs,
    resolvers
  })
})

class MyApp extends App {
  render() {
    const { Component, pageProps, apollo } = this.props;


    return (
      <ApolloProvider client={apollo}>
        <Component {...pageProps} />
      </ApolloProvider>
    );
  }
}

export default apolloClient(MyApp);

尝试过

  • 我尝试从withApollo 函数中访问localStorage,但它是SSR,所以我无法访问它。我打算使用localStorage 设置一个布尔值来检查withApollo 函数,以便在重定向后知道访问令牌已添加到阿波罗缓存中。
  • 我尝试使用缓存和存储布尔值的密钥来检查用户是否已登录,该登录设置在与访问令牌相同的函数中。如果这是真的,我将访问访问令牌密钥并将其添加到 Authorization 标头。但是我在设置初始状态以覆盖登录功能中设置的缓存时遇到问题。

其他想法

  • 我以为我可以在 ctx 参数中传递访问令牌,但我对 Next.js 不够熟悉,无法确定这是否是有效的方法。

    李>
  • 我以为我可以从组件中将 props 传递给 withApollo 函数,但这似乎不太可能。

问题

  • 存储访问密钥以便在每次请求时将其添加到 Apollo 客户端的最佳方式是什么?
  • 我注意到有些人正在使用fetch polyfill,这适合这种情况吗?如果是这样,那将如何运作?
  • withApollo HOC 是如何工作的,为什么它需要与 Next.js 一起工作?我已经阅读了这背后的一些代码,但我根本不明白为什么需要它。

【问题讨论】:

  • 如何获得令牌?前任。登录后?
  • 用户登录并被重定向。他们被重定向到的 URL 包含带有访问令牌的查询字符串。我从那里获取访​​问令牌并使用client.writeData() 将其添加到本地缓存中。我尝试使用client.writeQuery(),但出现错误。

标签: authorization apollo next.js react-apollo server-side-rendering


【解决方案1】:

我能够找到我的问题的解决方案。我只是不完全了解 Apollo 客户端以及如何使用所有必需的包。

解决方案

我使用了来自apollo-link-context 库的setContext。它是 Apollo Client 提供的 link 库集的一部分,用于在 graphql 操作开始后自定义网络请求。我在setContext 函数中设置了标题。像这样:

const authLink = setContext((_, { headers }) => {
  // It is also possible to use the local storage method in here.
  const data = cache.readQuery({
    query: ACCESS_TOKEN
  });

  return {
    headers: {
      ...headers,
      authorization: accessToken ? `Bearer ${data.accessToken}` : ""
    }
  }
});

以下内容在withApollo 函数之外。

const httpLink = new HttpLink({
  uri: '<server uri>',
});

下面是withApollo函数内部。

return new ApolloClient({
    cache,
    link: authLink.concat(httpLink),
    typeDefs,
    resolvers
  })

setContexthere 的文档以及 `apollo-link-context' 的文档是 here

【讨论】:

  • 嗨,你能告诉我你是如何用 Next.js 实现 apollo 客户端的吗,我也在使用 apollo 订阅,但起初当订阅没有找到任何令牌时它开始给我一个错误,没有找到令牌
  • 这是我在 Next.js 中使用 Apollo 客户端的项目,看看我是如何做到的:github.com/codeinaire/nmm-client/blob/main/graphql/…
  • 这仍在客户端发生,据我了解,您需要一个 cookie 才能在 SSR 期间访问令牌
  • @codeinaire 为什么authLink 会添加Access-Control-Allow-Origin 标头?我以为这个标头是由服务器在响应中设置的,不是吗?在客户端有什么用?
  • @avepr,你是对的!当时我还在学习请求、响应标头和 Apollo 客户端,所以并不真正知道标头是什么。感谢您指出!我会删除它以避免混淆。
猜你喜欢
  • 2020-12-16
  • 2015-05-17
  • 2019-12-24
  • 2017-08-31
  • 2018-12-01
  • 2016-06-15
  • 1970-01-01
  • 2021-04-21
  • 2021-09-19
相关资源
最近更新 更多