Maintaining API authentication using Axios

Matei Oprea
May 25, 2017 · 2 min read

This is a story about how we, at AmpLive, are maintaining users authenticated using axios.

Some time passed since my last story and I felt like it’s time to tell you more about what intrigued me a lot these days. After digging in on axios github issue page and Google, I found out that there’s no proper documented way of maintaining an user authenticated if you’re using React and axios.

How a request is served?

  1. Ask for data and send your Authentication Token
  2. API is verifying your payload, token and is querying the database
  3. Database responds with data to API
  4. API is sending data back

Simple, right? :) So, what happens if your Authentication Token has expired. You can’t ask the user to login again. It’s bad user experience. That’s why refresh tokens have been invented.

A refresh token allows the user to ask the API to issue a new token directly, without needing to re-authenticate.

So, let’s say your token just expired and you want to request some data from the API. JWT is composed from three layers: a header, a payload, and a signature. The payload have some reserved fields like issuer, expiration, subject and audience. So you can always check the expiration time if you don’t encode the token (remember: JWT tokens should be short-lived ~ 15 min — 1hour)

The diagram above will transform into the following:

  1. Ask for data and send the Auth token
  2. Verify token expiration time
  3. If the token is expired use axios interceptor to prevent the request from being made
  4. Save the original request and send another one to your token refresh endpoint in order to get a new valid JWT Token
  5. Resolve the initial request
  6. Get the data you asked for
  7. Be happy :)

Coding time, right?

client.interceptors.request.use((config) => {
let originalRequest = config;
if (tokenIsExpired && path_is_not_login) {
return issueToken().then((token) => {
originalRequest['Authorization'] = 'Bearer ' + token;
return Promise.resolve(originalRequest);
return config;
}, (err) => {
return Promise.reject(err);

For the sake of the example, let’s see the implementation for issueToken:

function issueToken() {
return new Promise((resolve, reject) => {
return client({
}).then((response) => {
}).catch((err) => {

Easy, right? ;)

Hope this helps you. It took me a while to research how to better use interceptors and to figure out when to send the re-auth request.

Happy coding!

Matei Oprea

Written by

Software Developer @ Okapi Studio / Music producer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade