Apollo client + Next.js - 向客户端请求添加授权令牌
Apollo client + Next.js - Adding Authorization token to client request
目标
我想用访问令牌填充我的 Authorization
header。我想将该访问令牌存储在 Apollo 缓存中,因为 Auth0 explicitly state not to store access tokens in local storage (I don't know why the 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
函数,这样它就会知道访问令牌已在重定向后添加到 apollo 缓存中。
- 我试过使用带有存储布尔值的密钥的缓存来检查用户是否已登录,该值设置在与访问令牌相同的函数中。如果是这样,我将访问访问令牌密钥并将其添加到
Authorization
header。但是我遇到了设置初始状态覆盖登录功能中设置的缓存的问题。
其他想法
我想我可以在 ctx
参数中传递访问令牌,但我对 Next.js 不够熟悉,无法确定这是否是有效的方法它.
我以为我可以从一个组件向 withApollo
函数传递一个 props,但这似乎不可能。
问题
- 存储访问密钥以便在每次请求时将其添加到 Apollo 客户端的最佳方式是什么?
- 我注意到有些人正在使用
fetch
polyfill,这适合这种情况吗?如果是这样,那将如何运作?
withApollo
HOC 是如何工作的,为什么需要它与 Next.js 一起工作?我已经阅读了这背后的一些代码,但我根本不明白为什么需要它。
我找到了问题的解决方案。我只是没有完全理解 Apollo Client 以及如何使用所有必需的包。
解决方案
我使用了 apollo-link-context
库中的 setContext
。它是 Apollo Client 提供的 link
库集的一部分,用于在 graphql 操作启动后自定义网络请求。我在 setContext
函数中设置了 header。像这样:
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
})
setContext
的文档 here and the docs for the `apollo-link-context' are here。
目标
我想用访问令牌填充我的 Authorization
header。我想将该访问令牌存储在 Apollo 缓存中,因为 Auth0 explicitly state not to store access tokens in local storage (I don't know why the 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
函数,这样它就会知道访问令牌已在重定向后添加到 apollo 缓存中。 - 我试过使用带有存储布尔值的密钥的缓存来检查用户是否已登录,该值设置在与访问令牌相同的函数中。如果是这样,我将访问访问令牌密钥并将其添加到
Authorization
header。但是我遇到了设置初始状态覆盖登录功能中设置的缓存的问题。
其他想法
我想我可以在
ctx
参数中传递访问令牌,但我对 Next.js 不够熟悉,无法确定这是否是有效的方法它.我以为我可以从一个组件向
withApollo
函数传递一个 props,但这似乎不可能。
问题
- 存储访问密钥以便在每次请求时将其添加到 Apollo 客户端的最佳方式是什么?
- 我注意到有些人正在使用
fetch
polyfill,这适合这种情况吗?如果是这样,那将如何运作? withApollo
HOC 是如何工作的,为什么需要它与 Next.js 一起工作?我已经阅读了这背后的一些代码,但我根本不明白为什么需要它。
我找到了问题的解决方案。我只是没有完全理解 Apollo Client 以及如何使用所有必需的包。
解决方案
我使用了 apollo-link-context
库中的 setContext
。它是 Apollo Client 提供的 link
库集的一部分,用于在 graphql 操作启动后自定义网络请求。我在 setContext
函数中设置了 header。像这样:
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
})
setContext
的文档 here and the docs for the `apollo-link-context' are here。