title: How should I handle JWT token refresh in my Redux app?
body: <p>Our Redux application use JWT tokens for authentication. The access_token expires every 15 minutes and the refresh_token expires every 30 days. Both of them are provided by our API every time you log in and stored in the browser's local storage. If a secure endpoint receives a request with an expired token, it returns a 401 HTTP error. </p>
  
  <p>Unfortunately, I don't know how to proceed to handle the refresh process without having a negative impact on the user. From a technical point of view, here is what I would like to achieve:</p>
  
  <ul>
  <li>Action creator calls the API with an expired token</li>
  <li>Client receives a 401 HTTP error</li>
  <li>Client triggers a function that calls the API to obtain a new token (by providing the refresh token). </li>
  <li>If the call fails (refresh_token is expired), prompt the user the re-enter its credentials to re-obtain both tokens then re-attempt the original request.</li>
  <li>If the call succeeds, re-attempt the original request.</li>
  </ul>
  
  <p>I would like to have a function that would handle the refreshing process and that would be called in the error handling portion of the action creator.</p>
  
  <p>Here is what I have tried so far:</p>
  
  <pre><code>    export function handleError(dispatch, current_func, error, handling) {
          if(error.response) {
              if(error.response.status === 401 &amp;&amp; readToken("token") !== null) {
                  return attemptTokenRefresh(dispatch, current_func)
              }
  
              if(error.response.status === 422 &amp;&amp; readToken("token") === null) {
                  return attemptTokenRefresh(dispatch, current_func)
              }
          }
  
          return(handling())
      }
  
      export function attemptTokenRefresh(dispatch, on_success) {
          let token = readToken("refresh_token");
  
          let instance = axios.create({
              headers: {"Authorization": token}
          });
  
          instance.post("api/refresh").then(response =&gt; {
              if (response.data["token"]) {
                  storeToken("token", response.data["token"]);
                  on_success();
              }
          }).catch(error =&gt; {
              //TODO: Allow user to sign back (prevent wiping the state)
          });
      }
  </code></pre>
  
  <p><em>dispatch</em> refers to the dispatch function provided by Redux</p>
  
  <p><em>current_func</em> refers to the action creator</p>
  
  <p><em>error</em> refers to the error returned by the API</p>
  
  <p><em>handling</em> refers to the error handling function for other types of errors</p>
  
  <p>Any help would be greatly appreciated :)</p>