因此,根据有关apollo-link-error的apollo文档,如果onError
与forward(operation)
一起使用,则可以用来处理重新认证。
所以我写了以下代码
import { ApolloClient } from 'apollo-client'
import { createHttpLink, HttpLink } from 'apollo-link-http'
import { setContext } from 'apollo-link-context'
import { InMemoryCache } from 'apollo-cache-inmemory'
import AsyncStorage from '@react-native-community/async-storage'
import { refresh } from 'react-native-app-auth'
import { onError } from 'apollo-link-error'
import { ApolloLink, from } from 'apollo-link'
import { RetryLink } from "apollo-link-retry"
import { KC_CONFIG } from '../../config/env'
const httpLink = new HttpLink({
uri: 'graphqlEndpointOfYourchoice'
})
const authLink = setContext(async (_, { headers }) => {
const accessToken = await AsyncStorage.getItem('accessToken')
const unwrappedAccessToken = JSON.parse(accessToken)
return {
headers: {
...headers,
authorization: unwrappedAccessToken ? `Bearer ${unwrappedAccessToken}` : "",
}
}
})
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
AsyncStorage.getItem('refreshToken')
.then(data => {
const refreshToken = JSON.parse(data)
// console.log(data)
refresh(KC_CONFIG, {
refreshToken,
})
.then(({ accessToken, refreshToken }) => {
const oldHeaders = operation.getContext().headers
operation.setContext({
...oldHeaders,
authorization: accessToken
})
console.log(oldHeaders.authorization)
console.log(accessToken)
// console.log(refreshToken)
AsyncStorage
.multiSet([
['accessToken', JSON.stringify(accessToken)],
['refreshToken', JSON.stringify(refreshToken)]
])
// tried putting forward() here <--------------
})
.catch(e => {
if (e.message === 'Token is not active') console.log('logging out')
else console.log('Refresh error: ' + e)
})
})
.then(() => {
console.log('Refreshed the accesstoken')
return forward(operation)
})
.catch(e => {
console.log('Storage error: ' + e)
})
}
if (networkError) {
console.log('network error: ' + networkError)
}
// tried putting forward() here <--------------
})
const retryLink = new RetryLink()
export const client = new ApolloClient({
link: from([
retryLink,
errorLink,
authLink,
httpLink
]),
cache: new InMemoryCache()
})
这没有达到期望的结果。 该错误会被捕获并正常运行,并按需刷新令牌,但从不执行第二个请求。