# Refresh token logic, pt - Fri 9th Oct, 2020 [Continuing yesterday's entry](https://hackmd.io/EpngQeERQxm1U2X65gBvVw), I finished adding the setup to "refresh" an expired access token: ```typescript= if ( networkError && 'statusCode' in networkError && (networkError.statusCode === 401) ) { console.log(`[Network error ${operation.operationName}]: ${networkError!.message}`) return new Observable((observer) => { SecureStrage.get('refresh_token').then((refreshToken) => { if (refreshToken) { getNewTokens() .then((refreshResponse) => { // got new tokens, save to secure storage Promise.all([ SecureStrage.set('access_token', refreshResponse.access_token), SecureStrage.set('refresh_token', refreshResponse.refresh_token), ]) .then(() => { // tokens set to storage, swap out headers operation.setContext(({ headers = {} }: { headers: Record<string, string> }) => ({ headers: { // Re-add old headers ...headers, // Switch out old access token for new one authorization: refreshResponse.access_token || null, }, })) const subscriber = { next: observer.next.bind(observer), error: observer.error.bind(observer), complete: observer.complete.bind(observer), } // Retry last failed request forward(operation).subscribe(subscriber) }) .catch((error) => { // No refresh or client token available, we force user to login observer.error(error) console.log('Error setting to storage: ', error) logOut('error') }) }) .catch((error) => { crashlytics().recordError(error) console.log('Something went wrong with Identity refresh: ', error) logOut('error') }) } else if (!refreshToken) { crashlytics().log('No refresh token. Logging user out') console.log('No refresh token. Logging user out') logOut('error') } }) }) } ``` As discussed yesterday, in order to update the auth status from within `onLink`, I used an Apollo reactive var, wrapped in a hook for easy use within React components: ```typescript= export type AuthStatusQuery = { authStatus: AuthStatus } export const GET_AUTH_STATUS = gql` query getAuthStatus { authStatus @client } ` export const useAuthStatus = (): [AuthStatus, ReactiveVar<AuthStatus>] => { const { data } = useQuery<AuthStatusQuery>(GET_AUTH_STATUS) const setAuthStatus = useCallback(authenticate, []) return [data?.authStatus ?? 'unknown', setAuthStatus] } ``` You could see reactive vars being very useful for things you might have previously used React Context for such as a flag to say if an app's hamburger menu is open. ###### tags: `programmingjournal` `2020` `C+` `auth` `reactivevariables` `apolloclient` `refreshtoken` `errorLink`