Axios: ¿Actualizar los encabezados de autenticación en cada solicitud?

Creado en 25 feb. 2018  ·  10Comentarios  ·  Fuente: axios/axios

Hola chicos,

Hice una nueva instancia de axios que utilizo para los recursos de api protegidos y le adjunté un encabezado de autenticación con token, pero el problema es que si voy a la consola y elimino tokem de localStorage, axios todavía lo envía como instancia no se actualizó.

¿Existe una solución para que mis encabezados de autenticación en la instancia puedan verificar el token en localStorage en cada solicitud?

¡Gracias!

Comentario más útil

He usado interceptores para este propósito. Si la URL base de la solicitud es a mi API, agrego el encabezado de autenticación (para evitar enviar credenciales a terceros). Esto se ejecuta en cada solicitud, por lo que si el token cambia (por ejemplo, como resultado de una actualización del token), la siguiente solicitud recoge el nuevo token. También me aseguro de verificar los valores existentes en la solicitud para permitir la anulación del encabezado del sitio de la llamada si eso fuera necesario por cualquier motivo.

axios.interceptors.request.use(
  config => {
    if (config.baseURL === baseApiAddress && !config.headers.Authorization) {
      const token = getToken();

      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
    }

    return config;
  },
  error => Promise.reject(error)
);

Todos 10 comentarios

Tengo un caso de uso similar en el que sería genial si los encabezados pasados ​​se evaluaran de manera perezosa para cada solicitud.

Pensó:
En lugar de pasar el hash de los encabezados con entusiasmo como un objeto ( axios.create({headers: {...}}) , podríamos pasar una función que devuelva los encabezados ( axios.create({headers: () => {...}} ) que se evaluarían antes de enviar la solicitud.

¿Qué piensas?
Editar: Esta es una propuesta, no creo que esto funcione en este momento.

Me encontré con el mismo caso de uso. Lo que terminé haciendo a corto plazo fue usar la función transformRequest . Definitivamente un truco y me encantaría ayudar a implementar un enfoque adecuado de carga diferida en la base de código.

Consulte a continuación el fragmento de código. auth() obtiene el token del usuario que ha iniciado sesión si está disponible.

let HTTP = axios.create({
  baseURL: baseurl,
  transformRequest: [function (data, headers) {
    headers['Authorization'] = auth()
    return JSON.stringify(data)
  }],
  headers: {
    'Content-Type': 'application/json'
  }
})

He usado interceptores para este propósito. Si la URL base de la solicitud es a mi API, agrego el encabezado de autenticación (para evitar enviar credenciales a terceros). Esto se ejecuta en cada solicitud, por lo que si el token cambia (por ejemplo, como resultado de una actualización del token), la siguiente solicitud recoge el nuevo token. También me aseguro de verificar los valores existentes en la solicitud para permitir la anulación del encabezado del sitio de la llamada si eso fuera necesario por cualquier motivo.

axios.interceptors.request.use(
  config => {
    if (config.baseURL === baseApiAddress && !config.headers.Authorization) {
      const token = getToken();

      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
    }

    return config;
  },
  error => Promise.reject(error)
);

@mattstrayer, ¿puedes mostrarme el método getToken ()? ¿Almacena su token en localStorage o AsyncStorage (React Native)? ¡Gracias por adelantado!

Terminé con esto.

axios.create({
  baseURL: '<your-api>',
  headers: {
    Authorization: {
      toString () {
        return `Bearer ${localStorage.getItem('token')}`
      }
    }
  }
})

No estoy seguro de si funciona en algún caso.

Mi archivo http.js :

import axios from 'axios';
import {store} from './store';

const http = axios.create ({
  baseURL: process.env.VUE_APP_ROOT_API,
  timeout: 1000,
  headers: {'Content-Type': 'application/json'},
});

http.interceptors.request.use (
  function (config) {
    const token = store.token;
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  function (error) {
    return Promise.reject (error);
  }
);

export default http;

Mi tienda, una simple "clase" get / set

export const store = {
    _username: '',
    _email: '',
    _token: '',

    isLogged () {
      return this.token
    },

    set username (str) {
      this._username = str
      localStorage.setItem('username',str)
    },
    get username () {
      return this._username || localStorage.getItem('username')
    },

    set email (str) {
      this._email = str
      localStorage.setItem('email',str)
    },
    get email () {
      return this._email || localStorage.getItem('email')
    },

    set token (str) {
      this._token = str
      localStorage.setItem('token',str)
    },
    get token () {
      return this._token || localStorage.getItem('token')
    }

  }

Mi servicio de usuario "clase":

import http from './http'

export const user = {
  ping: () => http.get('/users/ping'),
  save: (user) => http.post('/users', user)
}

y finalmente, mi implementación:

import {user} from '@/services'

 user.ping().then( r => {
      console.log(r.data)
    })

por cierto, process.env.VUE_APP_ROOT_API y @/services son cosas Vue ...

Resultado:
image

@danielschmitz gracias por ese ejemplo !!

Parece que todos se dieron cuenta de esto y que no es un error, así que voy a cerrar esto 🙂

Encontré útil envolver el interceptor en async / await para asegurarme de que mi token se configuró antes de que se activara la llamada a la API:

http.interceptors.request.use (
  async (config) => {
    const token = await getToken(); // slightly longer running function than example above
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  (error) => {
    return Promise.reject (error);
  }
);

He usado interceptores para este propósito. Si la URL base de la solicitud es a mi API, agrego el encabezado de autenticación (para evitar enviar credenciales a terceros). Esto se ejecuta en cada solicitud, por lo que si el token cambia (por ejemplo, como resultado de una actualización del token), la siguiente solicitud recoge el nuevo token. También me aseguro de verificar los valores existentes en la solicitud para permitir la anulación del encabezado del sitio de la llamada si eso fuera necesario por cualquier motivo.

axios.interceptors.request.use(
  config => {
    if (config.baseURL === baseApiAddress && !config.headers.Authorization) {
      const token = getToken();

      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
    }

    return config;
  },
  error => Promise.reject(error)
);

Interceptor parece la solución más elegante

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

samayo picture samayo  ·  3Comentarios

ghprod picture ghprod  ·  3Comentarios

tbaustin picture tbaustin  ·  3Comentarios

achingbrain picture achingbrain  ·  3Comentarios

ghost picture ghost  ·  3Comentarios