vlki / refresh-fetch

Wrapper around fetch capable of graceful authentication token refreshing.
MIT License
84 stars 12 forks source link

Refresh-fetch continue to use old token after refreshed and saved new token #13

Closed zola0592 closed 4 years ago

zola0592 commented 4 years ago

Token expire and refresh-fetch start refresh process and saved new token in localstorage but when repeated request it use old token which does'nt exist anymore in localstorage but when i refresh my page it use now the new token generated early.

Please can you help me. Thank best regards

vlki commented 4 years ago

Hey @zola0592, sounds like it is a problem with retrieving and saving of the token. Not sure what might be the problem just from the description. Post here the actual code in which you use refresh-fetch.

digingit commented 4 years ago

hey @vlki find under my fetch Config for retrieving and saving token :

// =============================================================================== // // =============================================================================== //

 // fetchJSON is bundled wrapper around fetch which simplifies working
// with JSON API:
//   * Automatically adds Content-Type: application/json to request headers
//   * Parses response as JSON when Content-Type: application/json header is
//     present in response headers
//   * Converts non-ok responses to errors
import { configureRefreshFetch, fetchJSON } from 'refresh-fetch'
import merge from 'lodash/merge'
import * as constants from './constants';

// Provide your favorite token saving -- to cookies, local storage, ...
const retrieveToken = () => { 
  try{
    return  JSON.parse(localStorage.getItem(constants.WSO2_CONFIG.WSO2_RESPONSE) || {}) ; 
  }catch(e){
    return  {} ; 
  } 
 }

const saveToken = token => { 
  localStorage.setItem(constants.OTHERS.ACCESS_TOKEN, token.access_token)
  localStorage.setItem(constants.WSO2_CONFIG.WSO2_RESPONSE, JSON.stringify(token))
  //console.log("Token setted successffully", localStorage.getItem(constants.WSO2_CONFIG.WSO2_RESPONSE));
  // localStorage.setItem(constants.WSO2_CONFIG.WSO2_RESPONSE, token); 
 }

const clearToken = () => { 
    localStorage.removeItem(constants.OTHERS.ACCESS_TOKEN);
    localStorage.removeItem(constants.WSO2_CONFIG.WSO2_RESPONSE); 
}

// Add token to the request headers
const fetchJSONWithToken = (url, options = {}) => {
  const token = retrieveToken()
  console.log(url, token.access_token)
  let optionsWithToken = options
  if (token != null) {

    //optionsWithToken = Object.assign({}, {headers: {Authorization: `Bearer ${token.access_token}`}}, optionsWithToken);

    optionsWithToken = merge({}, options, {
      headers: {
        Authorization: `Bearer ${token.access_token}`
      }
    })

  }

  return fetchJSON(url, optionsWithToken)
}

// Decide whether this error returned from API means that we want
// to try refreshing the token. error.response contains the fetch Response
// object, error.body contains the parsed JSON response body
const shouldRefreshToken = error =>
  error.response.status === 401
  && error.body.message === 'Full authentication is required to access this resource'

// Do the actual token refreshing and update the saved token
const refreshToken = () => {
    const token = retrieveToken();
  return fetchJSONWithToken(constants.API_URL.REFRESH_TOKEN + "?refreshToken="+ token.refresh_token +"&uri=null", {
    method: 'GET'
  })
    .then(res => {
         saveToken(res.body.response)
    })
    .catch(error => {
      // If we failed by any reason in refreshing, just clear the token,
      // it's not that big of a deal
      clearToken()
      throw error
    })
}

export const fetch = configureRefreshFetch({
  shouldRefreshToken,
  refreshToken,
  fetch: fetchJSONWithToken,
})
vlki commented 4 years ago

Weird. Don't see an issue with your code here. When calling fetchJSONWithToken you always get the token from local storage, so changing the token in local storage should then influence all the next calls to fetchJSONWithToken

vlki commented 4 years ago

Since you haven't responded, I hope you solved it then! So closing this issue. Open a new one in case you still have issues with refresh-fetch.