Closed ganzp87 closed 4 years ago
Hey there @ganzp87 - I believe that isTokenValidOrUndefined
is not an async function, so I think it'll always return a falsy value
@mikeislearning - Is there no way to use SecureStore or something async function ? I just want to keep the token in the secure-store.
@ganzp87
Here's how I set mine up.
isTokenValidOrUndefined
function is where I synchronously check the value of Time Context. If it is greater than 1 hour ago, I update Time Context, Auth Context, and the Secure Storage value all the handleFetch
functionYou could also use redux instead of context if you're more familiar with that.
Lemme know if that helps
@mikeislearning
I also use SecureStore in my Auth Context. However anyway the context using storage is a async function.
You mean that I have to add another setting something like sync time context for this package.
But I think your suggestion is inefficient, because the reason I use this package is just for convenience.
My jwt token last just 5 min. Therefore the token in every request should be checked.
Now I am not using this. I made a similiar async function with TokenRefreshLink for using SecureStore. I check a token is valid and if token expired, reissue and get by myself.
I might not understand your suggestion well. but that seems to be Inefficient.
The one thing that I want to know is why token validating process should be sync function and if it is async function, I wonder if it can cause serious problems
Hey @ganzp87 the longer I use the package, the less success I'm having with it. I was able to get it working like a year ago with Apollo Client v2, and I think that's what this was built for. I'll keep plugging away to try and get it to work. Lemme know if you have any luck
@mikeislearning This is what I made. I want it to help you
new ApolloClient({
link: ApolloLink.from([
requestLink,
...
)]
})
let isRefreshing = false
let pendingRequests = []
const resolvePendingRequests = () => {
pendingRequests.map((callback) => callback())
pendingRequests = []
}
const requestLink = new ApolloLink((operation, forward) => {
const { operationName } = operation
const operNoNeededToken = ['operation name that you don't want to refetch a token']
if (!operNoNeededToken.includes(operationName)) {
let forward$
if (!isRefreshing) {
isRefreshing = true
forward$ = fromPromise(
refetchAccessToken(operationName)
.then((token) => {
resolvePendingRequests()
return token
})
.catch((error) => {
pendingRequests = []
return
})
.finally(() => {
isRefreshing = false
})
).filter((value) => Boolean(value))
} else {
forward$ = fromPromise(
new Promise((resolve) => {
pendingRequests.push(() => resolve())
})
)
}
return forward$.flatMap(() => forward(operation))
} else {
return new Observable((observer) => {
let handle
Promise.resolve(operation)
.then(() => {
handle = forward(operation).subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
})
})
.catch(observer.error.bind(observer))
return () => {
if (handle) handle.unsubscribe()
}
})
}
})
export const refetchAccessToken = async () => {
const _this = this
const token = (await SecureStore.getItemAsync("jwt")) ?? getAccessToken()
if (token) {
const { exp } = jwtDecode(token)
if (Date.now() <= exp * 1000) {
accessToken = token
return token
}
}
const result = await fetch(httpsUrlOption("refresh_token"), {
method: "POST",
credentials: "include",
})
try {
const { accessToken: aToken, ok } = await result.json()
console.log(aToken, ok)
if (!ok) {
console.log("logout because the token is invalid")
} else {
await SecureStore.setItemAsync("isLoggedIn", "true")
await SecureStore.setItemAsync("jwt", aToken)
const { exp } = jwtDecode(aToken)
if (Date.now() <= exp * 1000) {
accessToken = aToken
return aToken
}
}
setAccessToken(aToken)
return aToken
} catch (error) {
throw Error(error)
}
}
export const setAccessToken = (s) => {
accessToken = s
}
export const getAccessToken = () => {
return accessToken
}
It doesn't work when using ApolloLink. when I request something, the tokenRefreshLink start and end in isTokenValidOrUndefined() fetchAccessToken, handleFetch and other function don't work