我在ReactJS中使用Apollo客户端与GraphQL API进行通信。我们使用Firebase身份验证,它使用JWT来确保我们的API不会向公众公开私有数据,但问题是Firebase令牌每隔一小时左右就会过期。
当用户登录并在请求标头上使用它时,我当前正在保存IdToken localstorage,但是当令牌过期时,graphql返回Non Authorized错误。我也尝试过从阿波罗的createHttpLink函数上使用customfetch
const customFetch = async (uri, options) => {
console.log(firebase.auth.currentUser)
if (firebase.auth.currentUser) {
const token = await firebase.auth.currentUser.getIdToken()
localStorage.setItem('token', token)
options.headers.authorization = token;
return fetch(uri, options);
}
else {
firebase.auth.onAuthStateChanged(async (user) => {
if (user) {
console.log('Inside on Auth')
const token = await user.getIdToken()
localStorage.setItem('token', token)
options.headers.authorization = token;
return fetch(uri, options);
}
})
}
console.log('End of Fetch')
};
但在firebase.auth.onAuthStateChanged完成之前获取已完成,因此它也无法工作
答案 0 :(得分:1)
将其设为自定义链接,而不是自定义提取。
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
import firebase from 'firebase/app'
import 'firebase/app'
import { setContext } from 'apollo-link-context'
const authLink = setContext((_, { headers }) => {
//it will always get unexpired version of the token
return firebase
.auth()
.currentUser.getIdToken()
.then((token) => {
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ''
}
}
})
})
const link = ApolloLink.from([authLink, ...{/**ur other links */}])
const client = new ApolloClient({
ssrMode: typeof window !== 'undefined',
cache: new InMemoryCache().restore({}),
link
})
答案 1 :(得分:0)
我为此使用递归,但是不确定是否存在任何问题。
firebase.auth.onAuthStateChanged(async (user) => {
if (user) {
setToken(user)
}
})
const setToken = async (user) => {
const token = await user.getIdToken();
localStorage.setItem("token", token);
setTimeout(() => setToken(user), 59000);
}