【发布时间】:2018-11-09 19:59:34
【问题描述】:
我正在尝试实现 Apollo docs 中正式描述的 Authentication 工作流程,就像我之前在其他项目中所做的那样,但这次使用的是 Gatsby。
这个想法似乎很简单。需要像使用redux 时一样创建/更新gatsby-browser.js,但要初始化ApolloClient 并通过ApolloProvider。
类似:
import React from 'react'
import { Router } from 'react-router-dom'
import { ApolloProvider } from 'react-apollo'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
const httpLink = createHttpLink({
uri: process.env.ENDPOINT_URI,
credentials: 'same-origin',
})
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
})
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache().restore({}),
})
exports.replaceRouterComponent = ({ history }) => {
const ConnectedRouterWrapper = ({ children }) => (
<ApolloProvider client={client}>
<Router history={history}>{children}</Router>
</ApolloProvider>
)
return ConnectedRouterWrapper
}
然后登录使用
<Mutation
mutation={LOGIN_MUTATION}
refetchQueries={[{ query: CURRENT_USER_QUERY }]}
>
{/*...*/}
</Mutation>
在另一个 Component 中带有类似 Status 的内容(如果已登录,则显示 x,否则为 y):
<Query query={CURRENT_USER_QUERY} fetchPolicy="network-only">
{/*...*/}
</Query>
问题
使用此配置,当登录接收到data(因此,凭据没问题)时,我将收到的令牌保存在localStorage 但Status 组件使用前面的Query (空)token,所以显示已注销,登录后也会执行history.push('/') 之类的操作。
刷新页面,由于localStorage中的项目之前保存过,状态显示为已登录。
预期行为
这个想法是在登录后更新 Status 组件以避免刷新页面,为此我添加了refetchQueries={[{ query: CURRENT_USER_QUERY }]}。
我尝试了一些方法,例如通过 props(如果我更改 route 并在 Status 组件中使用 withRouter,则不需要),但似乎迟到了,Query在没有新的token 的情况下被解雇。
【问题讨论】:
标签: reactjs apollo react-apollo apollo-client gatsby