目前,当我使用firebase验证用户时,我会将他们的auth令牌存储在localStorage
中,以便稍后连接到我的后端,如下所示:
const httpLink = new HttpLink({uri: 'http://localhost:9000/graphql'})
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization token to the headers
const token = localStorage.getItem(AUTH_TOKEN) || null
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
})
return forward(operation)
})
const authAfterware = onError(({networkError}) => {
if (networkError.statusCode === 401) AuthService.signout()
})
function createApolloClient() {
return new ApolloClient({
cache: new InMemoryCache(),
link: authMiddleware.concat(authAfterware).concat(httpLink)
})
}
我遇到的问题是,令牌过期后我无法刷新它,所以我尝试使用下面的代码来设置apollo的授权令牌:
const httpLink = new HttpLink({uri: 'http://localhost:9000/graphql'})
const asyncAuthLink = setContext(
() => {
return new Promise((success, reject) => {
firebase.auth().currentUser.getToken().then(token => {
success({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
})
}).catch(error => {
reject(error)
})
})
}
)
const authAfterware = onError(({networkError}) => {
if (networkError.statusCode === 401) AuthService.signout()
})
function createApolloClient() {
return new ApolloClient({
cache: new InMemoryCache(),
link: asyncAuthLink.concat(authAfterware.concat(httpLink))
})
}
这在用户第一次认证时有效,但一旦用户刷新页面,当我的graphql查询发送到我的后端时,firebase就不再初始化,所以令牌不会随它一起发送。是否有一种方法可以异步地等待firebase.auth().currentUser
,这样就可以正常工作?或者是否有另一种方法可以完全采用?据我所知(100%肯定)currentUser.getIdToken
只在当前令牌不再有效时才进行网络调用。我认为这是可以接受的,因为在令牌无效的情况下,后端无论如何都无法响应,所以我需要等待令牌刷新才能继续。
我想到了一些其他的想法:
- 继续使用
localStorage
来存储auth令牌,如果我的后端发送回401响应,则在authAfterware
中刷新它,并重试请求。 - 设置获取身份验证令牌的延迟(不可取)
- 还有别的主意吗?
谢谢!
1条答案
按热度按时间z9smfwbn1#
我知道有点晚了,但我也被困在这个问题上,并找到了解决它的方法。也许这不是最好的方法,但至少它是有效的。我的方法是创建一个Next API端点来使用getUserFromCookies方法检索用户令牌:
然后在apollo客户端配置中调用此端点,如下所示:
希望能有所帮助!