Search code examples
vuejs2interceptor

Vue.js Persist body with interceptors


Hello I am using interceptors to get a refresh token, if I receive 401 error

This is the code:

httpClient.interceptors.response.use(
  (response) => {
    const end = Date.now()
    console.info(`Api Call ${response.config.url} took ${end - response.config.config.start}ms`)
    return response
  },
  async (error) => {
    const originalRequest = error.config
    if (error.response.status === 401 && originalRequest.url.includes('auth/token')) {
      // Do something
      store.commit('clearUserData')
      return Promise.reject(error)
    } else if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true
      await store.dispatch('auth/refreshToken')
      return httpClient(originalRequest)
    }
    return Promise.reject(error)
  }
)

I sent to console (Server Side) the behavior of API calls to try to explain better, here the output:

01|appapi  | 2021-06-29T14:24:05: PATCH: /products/60db632ad91cfa6b2200145f
02|appapi  | 2021-06-29T14:24:05: {
03|appapi  |   product: 'test',
04|appapi  |   description: 'test description',
05|appapi  |   rate: 19,
06|appapi  |   image: '/products/JV2zwoZicGEAXJW4.jpg',
07|appapi  |   category: '5f6121c306e8bc0854d9ceb3',
08|appapi  |   active: true
09|appapi  | }
10|appapi  | 2021-06-29T14:24:05: Hostname: url.api.com, IP: 192.168.1.100
11|appapi  | 2021-06-29T14:24:05: POST: /auth/token
12|appapi  | 2021-06-29T14:24:05: { token: '67cqmmt6YUAgdP3w' }
13|appapi  | 2021-06-29T14:24:05: Hostname: url.api.com, IP: 192.168.1.100
14|appapi  | 2021-06-29T14:24:05: PATCH: /products/60db632ad91cfa6b2200145f
15|appapi  | 2021-06-29T14:24:05: {}

As you can see:

I request a patch with payload (Lines 01 to 09)
As the token expired, interceptors go to refresh token with payload(Lines 10-12)
When interceptor go for original request again, the body is gone (Lines 13-15)

What did I do wrong? why is the body content lost? I will appreciate all the help

Sorry for my bad English


Solution

  • Finally after so much debugging I found the solution. The problem was that the headers are lost when re-executing the request, then I will put the code before and after the solution:

    Before

    const httpClient = axios.create({
      baseURL: process.env.VUE_APP_BASE_URL_API,
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      timeout: 10000,
    })
    
    httpClient.interceptors.request.use((req) => {
      req.config = {
        ...(req.config ?? {}),
        start: Date.now(),
      }
      if (req.url.includes('productos')) {
        const token = store.getters['auth/accessToken']
        req.headers = {
          Authorization: `Bearer ${token}`,
        }
      }
      return req
    })
    

    After

    I added Accept: 'application/json','Content-Type': 'application/json', in headers object

    httpClient.interceptors.request.use((req) => {
      req.config = {
        ...(req.config ?? {}), // preserve a given request.config object
        start: Date.now(),
      }
      if (req.url.includes('productos')) {
        const token = store.getters['auth/accessToken']
        req.headers = {
          Authorization: `Bearer ${token}`,
          Accept: 'application/json',
          'Content-Type': 'application/json',
        }
      }
      return req
    })