Axios: Auth-Header bei jeder Anfrage aktualisieren?

Erstellt am 25. Feb. 2018  ·  10Kommentare  ·  Quelle: axios/axios

Hallo Leute,

Ich habe eine neue Instanz des Axios erstellt, die ich für die geschützten API-Ressourcen verwende, und ich habe den Auth-Header mit Token angehängt, aber das Problem ist, wenn ich zur Konsole gehe und Token aus localStorage lösche, sendet Axios es immer noch als Instanz wurde nicht aktualisiert.

Gibt es eine Lösung, damit meine Authentifizierungsheader in der Instanz in jeder Anfrage nach Token in localStorage suchen können?

Danke!

Hilfreichster Kommentar

Ich habe zu diesem Zweck Abfangjäger verwendet. Wenn die Basis-URL der Anfrage an meine API gerichtet ist, füge ich den Authentifizierungsheader hinzu (um das Senden von Anmeldeinformationen an Dritte zu verhindern). Dies wird bei jeder Anforderung ausgeführt. Wenn sich also der Token ändert (z. B. als Ergebnis einer Token-Aktualisierung), nimmt die nächste Anforderung den neuen Token entgegen. Ich stelle auch sicher, dass ich in der Anforderung nach vorhandenen Werten suche, um das Überschreiben des Headers von der Anrufseite zu ermöglichen, wenn dies aus irgendeinem Grund erforderlich ist.

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

Alle 10 Kommentare

Ich habe einen ähnlichen Anwendungsfall, bei dem es großartig wäre, wenn die übergebenen Header für jede Anfrage träge ausgewertet würden.

Habe gedacht:
Anstatt den Header-Hash eifrig als Objekt ( axios.create({headers: {...}}) , könnten wir eine Funktion übergeben, die die Header ( axios.create({headers: () => {...}} ) zurückgibt, die ausgewertet werden, bevor die Anfrage gesendet wird.

Was denkst du?
Edit: Dies ist ein Vorschlag, ich glaube nicht, dass das im Moment funktioniert.

Ich bin auf den gleichen Anwendungsfall gestoßen. Kurzfristig habe ich die Funktion transformRequest verwendet. Auf jeden Fall ein Hack und würde gerne helfen, einen richtigen Lazy-Loading-Ansatz in die Codebasis zu implementieren.

Siehe unten für das Code-Snippet. auth() ruft das Token des angemeldeten Benutzers ab, falls verfügbar.

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

Ich habe zu diesem Zweck Abfangjäger verwendet. Wenn die Basis-URL der Anfrage an meine API gerichtet ist, füge ich den Authentifizierungsheader hinzu (um das Senden von Anmeldeinformationen an Dritte zu verhindern). Dies wird bei jeder Anforderung ausgeführt. Wenn sich also der Token ändert (z. B. als Ergebnis einer Token-Aktualisierung), nimmt die nächste Anforderung den neuen Token entgegen. Ich stelle auch sicher, dass ich in der Anforderung nach vorhandenen Werten suche, um das Überschreiben des Headers von der Anrufseite zu ermöglichen, wenn dies aus irgendeinem Grund erforderlich ist.

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 können Sie mir die Methode getToken() zeigen? Speichern Sie Ihr Token in localStorage oder AsyncStorage (React Native)? Vielen Dank im Voraus!

Ich bin damit fertig geworden.

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

Ich bin mir nicht sicher, ob es in jedem Fall funktioniert.

Meine http.js Datei:

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;

Mein Shop, eine einfache Get/Set-"Klasse"

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')
    }

  }

Mein Benutzerdienst "Klasse":

import http from './http'

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

und endlich meine Umsetzung:

import {user} from '@/services'

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

Übrigens, process.env.VUE_APP_ROOT_API und @/services sind Vue-Dinge ...

Ergebnis:
image

@danielschmitz danke für dieses Beispiel!!

Sieht so aus, als hättet ihr das herausgefunden und es ist kein Fehler, also schließe ich das aus 🙂

Ich fand es nützlich, den Interceptor in async/await einzuschließen, um sicherzustellen, dass mein Token gesetzt wurde, bevor der API-Aufruf ausgelöst wurde:

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

Ich habe zu diesem Zweck Abfangjäger verwendet. Wenn die Basis-URL der Anfrage an meine API gerichtet ist, füge ich den Authentifizierungsheader hinzu (um das Senden von Anmeldeinformationen an Dritte zu verhindern). Dies wird bei jeder Anforderung ausgeführt. Wenn sich also der Token ändert (z. B. als Ergebnis einer Token-Aktualisierung), nimmt die nächste Anforderung den neuen Token entgegen. Ich stelle auch sicher, dass ich in der Anforderung nach vorhandenen Werten suche, um das Überschreiben des Headers von der Anrufseite zu ermöglichen, wenn dies aus irgendeinem Grund erforderlich ist.

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 scheint die eleganteste Lösung zu sein

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

tbaustin picture tbaustin  ·  3Kommentare

ghprod picture ghprod  ·  3Kommentare

altruisticsoftware picture altruisticsoftware  ·  3Kommentare

achingbrain picture achingbrain  ·  3Kommentare

Adman picture Adman  ·  3Kommentare