Comment envoyer un en-tête d'autorisation avec axios

96

Comment puis-je envoyer un en-tête d'authentification avec un jeton via axios.js? J'ai essayé quelques trucs sans succès, par exemple:

const header = `Authorization: Bearer ${token}`;
return axios.get(URLConstants.USER_URL, { headers: { header } });

Me donne cette erreur:

XMLHttpRequest cannot load http://localhost:8000/accounts/user/. Request header field header is not allowed by Access-Control-Allow-Headers in preflight response.

J'ai réussi à le faire fonctionner en définissant la valeur par défaut globale, mais je suppose que ce n'est pas la meilleure idée pour une seule demande:

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

Mettre à jour :

La réponse de Cole m'a aidé à trouver le problème. j'utilise middleware django-cors-headers qui gère déjà l'en-tête d'autorisation par défaut.

Mais j'ai pu comprendre le message d'erreur et corriger une erreur dans mon code de requête axios, qui devrait ressembler à ceci

return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
foobar
la source

Réponses:

87

Sur les requêtes http non simples, votre navigateur enverra d'abord une requête "Preflight" (une requête de méthode OPTIONS) afin de déterminer ce que le site en question considère comme des informations sûres à envoyer (voir ici les spécifications de la politique d'origine croisée à ce sujet). L'un des en-têtes pertinents que l'hôte peut définir dans une réponse de contrôle en amont est Access-Control-Allow-Headers. Si l'un des en-têtes que vous souhaitez envoyer n'était pas répertorié dans la liste des en-têtes de liste blanche de la spécification ou dans la réponse de contrôle en amont du serveur, le navigateur refusera d'envoyer votre demande.

Dans votre cas, vous essayez d'envoyer un en- Authorizationtête, qui n'est pas considéré comme l'un des en-têtes universellement sûrs. Le navigateur envoie ensuite une demande de contrôle en amont pour demander au serveur s'il doit envoyer cet en-tête. Le serveur envoie soit un en- Access-Control-Allow-Headerstête vide (ce qui signifie "ne pas autoriser les en-têtes supplémentaires") soit il envoie un en-tête qui ne comprend pas Authorizationdans sa liste d'en-têtes autorisés. Pour cette raison, le navigateur n'enverra pas votre demande et choisit à la place de vous avertir en lançant une erreur.

Toute solution de contournement Javascript que vous trouvez qui vous permet d'envoyer cette demande de toute façon doit être considérée comme un bogue car elle va à l'encontre de la politique de demande d'origine croisée que votre navigateur essaie d'appliquer pour votre propre sécurité.

tl; dr - Si vous souhaitez envoyer des en-Authorizationtêtes, il vaut mieux que votre serveur soit configuré pour l'autoriser. Configurez votre serveur pour qu'il réponde à uneOPTIONSdemande à cette URL avec un en-Access-Control-Allow-Headers: Authorizationtête.

Cole Erickson
la source
11
Merci, Cole! Votre réponse m'a aidé à trouver le problème. J'utilise le middleware django-cors-headers qui gère déjà l'en-tête d'autorisation par défaut. Mais j'ai pu comprendre le message d'erreur et corrigé une erreur dans mon code de requête axios, qui devrait ressembler à ceci return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
foobar
1
Vous êtes les bienvenus! Je rencontre tout le temps ce genre de problème avec mes API. Je suis juste content de pouvoir vous aider à comprendre le processus à suivre.
Cole Erickson le
43

Essaye ça :

axios.get(
    url,
    {headers: {
        "name" : "value"
      }
    }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );
Matija Župančić
la source
1
Ainsi, le nom de l'en-tête sera 'Access-Control-Allow-Headers' et la valeur est ce que vous voulez.
Matija Župančić
Donc, vous voulez dire que j'aurais quelque chose comme: axios.get (url, {headers: {'Access-Control-Allow-Headers': 'Bearer <my token>'}})? Cela ne marche pas.
foobar
11
Je crois que ça devrait être {'Authorization': 'Bearer <my token>'}
John Harding
35

Cela a fonctionné pour moi:

let webApiUrl = 'example.com/getStuff';
let tokenStr = 'xxyyzz';
axios.get(webApiUrl, { headers: {"Authorization" : `Bearer ${tokenStr}`} });
sean717
la source
Il y a moins de détails dans la réponse par rapport à ce qui précède, mais c'est la réponse que tout le monde recherche quand ils recherchent Google.
Black Mamba
32

Plutôt que de l'ajouter à chaque requête, vous pouvez simplement l'ajouter comme configuration par défaut comme ceci.

axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` 
Canaan Etai
la source
comment placez-vous cette configuration? à la racine (index.js, App.js)? Ou dans un fichier séparé?
ibubi
8

Vous avez presque raison, ajustez simplement votre code de cette façon

const headers = { Authorization: `Bearer ${token}` };
return axios.get(URLConstants.USER_URL, { headers });

remarquez où je place les backticks, j'ai ajouté `` après Bearer, vous pouvez omettre si vous serez sûr de gérer du côté serveur

Jalasem
la source
6
Normalement (selon les spécifications) il y a un espace, pas un tiret ( -), entre le schéma d'authentification et le jeton. Je n'ai jamais vu aucun type de serveur exiger un tiret comme vous l'avez montré, et la plupart sinon tous renverraient une erreur s'il en était fourni un.
Raman
6

Au lieu d'appeler la fonction axios.get, utilisez:

axios({ method: 'get', url: 'your URL', headers: { Authorization: `Bearer ${token}` } })
Deepak
la source
0
res.setHeader('Access-Control-Allow-Headers',
            'Access-Control-Allow-Headers, Origin,OPTIONS,Accept,Authorization, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');

Blockquote: vous devez ajouter OPTIONS & Authorization au setHeader ()

ce changement a résolu mon problème, essayez!

MESDOUR
la source
0

Installez le cors middleware. Nous essayions de le résoudre avec notre propre code, mais toutes les tentatives ont lamentablement échoué.

Cela l'a fait fonctionner:

cors = require('cors')
app.use(cors());

Lien d'origine

sonnerie
la source
ceci est pour les serveurs de nœuds, pas pour axios
Marc Garcia
Les utilisateurs qui trouvent cette question peuvent trouver cette réponse utile. Cette question peut être utilisée pour travailler avec des serveurs de nœuds dans des cas d'utilisation, et être un rappel que les cors peuvent résoudre leur problème, ou pour déplacer leur vérification d'en-tête backend sous le code ci-dessus. Cela m'a aidé à sauver tant de frustration, Merci.
DORRITO
0

Vous pouvez essayer ceci.

axios.get(
    url,
    {headers: {
            "Access-Control-Allow-Origin" : "*",
            "Content-type": "Application/json",
            "Authorization": `Bearer ${your-token}`
            }   
        }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );
Ashish
la source