Axios: Mettre Ă  jour les en-tĂȘtes d'authentification Ă  chaque requĂȘte ?

CrĂ©Ă© le 25 fĂ©vr. 2018  Â·  10Commentaires  Â·  Source: axios/axios

Bonjour gars,

J'ai crĂ©Ă© une nouvelle instance de l'axios que j'utilise pour les ressources api protĂ©gĂ©es et j'y ai attachĂ© un en-tĂȘte d'authentification avec un jeton, mais le problĂšme est que si je vais Ă  la console et supprime le tokem de localStorage, axios l'envoie toujours en tant qu'instance n'a pas Ă©tĂ© mis Ă  jour.

Existe-t-il une solution pour que mes en-tĂȘtes d'authentification dans l'instance puissent vĂ©rifier le jeton dans localStorage dans chaque demande ?

Merci!

Commentaire le plus utile

J'ai utilisĂ© des intercepteurs Ă  cette fin. Si l'URL de base de la demande correspond Ă  mon API, j'ajoute l'en-tĂȘte auth (pour empĂȘcher l'envoi d'informations d'identification Ă  des tiers). Ceci est exĂ©cutĂ© Ă  chaque demande, donc si le jeton change (par exemple Ă  la suite d'une actualisation du jeton), la demande suivante rĂ©cupĂšre le nouveau jeton. Je m'assure Ă©galement de vĂ©rifier les valeurs existantes dans la demande pour permettre le remplacement de l'en-tĂȘte du site d'appel si cela s'avĂ©rait nĂ©cessaire pour une raison quelconque.

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)
);

Tous les 10 commentaires

J'ai un cas d'utilisation similaire oĂč ce serait formidable si les en-tĂȘtes transmis Ă©taient Ă©valuĂ©s paresseusement pour chaque demande.

Pensée:
Au lieu de passer le hachage des en-tĂȘtes avec empressement en tant qu'objet ( axios.create({headers: {...}}) nous pourrions passer une fonction qui renvoie les en-tĂȘtes ( axios.create({headers: () => {...}} ) qui seraient Ă©valuĂ©s avant l'envoi de la requĂȘte.

Qu'en penses-tu?
Edit : Ceci est une proposition, je ne pense pas que cela fonctionne pour le moment.

Je suis tombĂ© sur le mĂȘme cas d'utilisation. Ce que j'ai fini par faire Ă  court terme, c'est d'utiliser la fonction transformRequest . Certainement un hack et j'adorerais aider Ă  mettre en Ɠuvre une approche de chargement paresseux appropriĂ©e dans la base de code.

Voir ci-dessous pour l'extrait de code. auth() obtient le jeton de l'utilisateur connecté s'il est disponible.

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

J'ai utilisĂ© des intercepteurs Ă  cette fin. Si l'URL de base de la demande correspond Ă  mon API, j'ajoute l'en-tĂȘte auth (pour empĂȘcher l'envoi d'informations d'identification Ă  des tiers). Ceci est exĂ©cutĂ© Ă  chaque demande, donc si le jeton change (par exemple Ă  la suite d'une actualisation du jeton), la demande suivante rĂ©cupĂšre le nouveau jeton. Je m'assure Ă©galement de vĂ©rifier les valeurs existantes dans la demande pour permettre le remplacement de l'en-tĂȘte du site d'appel si cela s'avĂ©rait nĂ©cessaire pour une raison quelconque.

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 pouvez-vous me montrer la méthode getToken() ? Stockez-vous votre jeton dans localStorage ou AsyncStorage (React Native) ? Merci d'avance!

J'ai fini avec ça.

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

Je ne sais pas si cela fonctionne dans tous les cas.

Mon fichier 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;

Mon magasin, une simple "classe" 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')
    }

  }

Mon service utilisateur "classe":

import http from './http'

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

et enfin, mon implémentation :

import {user} from '@/services'

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

d'ailleurs, process.env.VUE_APP_ROOT_API et @/services sont des choses de Vue...

RĂ©sultat:
image

@danielschmitz merci pour cet exemple !!

On dirait que vous avez tous compris cela et que ce n'est pas un bug, alors je ferme ça 🙂

J'ai trouvé utile d'envelopper l'intercepteur dans async/wait pour m'assurer que mon jeton était défini avant le déclenchement de l'appel d'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);
  }
);

J'ai utilisĂ© des intercepteurs Ă  cette fin. Si l'URL de base de la demande correspond Ă  mon API, j'ajoute l'en-tĂȘte auth (pour empĂȘcher l'envoi d'informations d'identification Ă  des tiers). Ceci est exĂ©cutĂ© Ă  chaque demande, donc si le jeton change (par exemple Ă  la suite d'une actualisation du jeton), la demande suivante rĂ©cupĂšre le nouveau jeton. Je m'assure Ă©galement de vĂ©rifier les valeurs existantes dans la demande pour permettre le remplacement de l'en-tĂȘte du site d'appel si cela s'avĂ©rait nĂ©cessaire pour une raison quelconque.

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 semble ĂȘtre la solution la plus Ă©lĂ©gante

Cette page vous a été utile?
0 / 5 - 0 notes