Envoi du jeton porteur avec axios

118

Dans mon application React, j'utilise axios pour exécuter les requêtes API REST.

Mais il ne peut pas envoyer l'en- tête d' autorisation avec la demande.

Voici mon code:

tokenPayload() {
  let config = {
    headers: {
      'Authorization': 'Bearer ' + validToken()
    }
  }
  Axios.post( 
      'http://localhost:8000/api/v1/get_token_payloads',
      config
    )
    .then( ( response ) => {
      console.log( response )
    } )
    .catch()
}

Ici, la validToken()méthode renvoie simplement le jeton du stockage du navigateur.

Toutes les demandes ont une réponse d'erreur de 500 indiquant que

Le jeton n'a pas pu être analysé à partir de la demande

depuis le back-end.

Comment envoyer l'en-tête d'autorisation avec chaque demande? Recommanderiez-vous un autre module avec react?

rakibtg
la source
Je ne pense pas du tout que ce soit un axiosproblème. vérifiez votre validToken()fonction, elle renvoie quelque chose que votre serveur ne comprend pas.
xiaofan2406
J'ai vérifié deux fois la fonction et j'ai également utilisé la chaîne de jeton ici au lieu de la fonction, toujours la même
rakibtg

Réponses:

140
const config = {
    headers: { Authorization: `Bearer ${token}` }
};

const bodyParameters = {
   key: "value"
};

Axios.post( 
  'http://localhost:8000/api/v1/get_token_payloads',
  bodyParameters,
  config
).then(console.log).catch(console.log);

Le premier paramètre est l'URL.
Le second est le corps JSON qui sera envoyé avec votre demande.
Le troisième paramètre sont les en-têtes (entre autres). Ce qui est également JSON.

Docteur
la source
4
Vous avez manqué un espace entre le porteur et le jeton - alors cela fonctionnera.
décembre
Message du médecin: "key:" value "a une citation qui devrait être supprimée ... Mais la correction qui a permis à l'authentification de fonctionner pour mon application native de réaction.
mediaguru
1
@mediaguru Thx pour le commentaire. Je l'ai réparé (je suppose)! La citation doit avoir été introduite par quelqu'un qui édite la réponse ...
Docteur
2
Bearerdevrait être utilisé avec B majuscule, n'est-ce pas?
Alizadeh118
1
@ Alizadeh118 Oui, selon la spécification HTTP. Mais de nombreuses API n'insistent pas sur la bonne capitalisation.
OneHoopyFrood
61

Voici une façon unique de définir un jeton d'autorisation dans axios. Définir la configuration pour chaque appel axios n'est pas une bonne idée et vous pouvez modifier le jeton d'autorisation par défaut en:

import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:1010/'
axios.defaults.headers.common = {'Authorization': `bearer ${token}`}
export default axios;

Edit , merci à Jason Norwood-Young.

Certaines API exigent que le porteur soit écrit en tant que porteur, vous pouvez donc faire:

axios.defaults.headers.common = {'Authorization': `Bearer ${token}`}

Vous n'avez plus besoin de définir la configuration pour chaque appel d'API. Désormais, le jeton d'autorisation est défini sur chaque appel axios.

Ilyas Karim
la source
18
Bearerdoit être capitalisé pour certaines API (j'ai découvert à la dure).
Jason Norwood-Young
23

Vous pouvez créer une configuration une fois et l'utiliser partout.

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'Authorization': 'Bearer '+token}
});

instance.get('/path')
.then(response => {
    return response.data;
})
Sarvar Nishonboev
la source
D'où la valeur du jeton est-elle transmise dans cet exemple? Pour mon application, le jeton serait renvoyé à l'API dans l'en-tête ou dans le corps après une connexion réussie.
Ken
c'est iciheaders: {'Authorization': 'Bearer '+token}
M.suleman Khan
Comment transmettre des données s'il s'agit d'une requête POST
M.suleman Khan
Pour ceux qui se demandent d'où la valeur du jeton peut être transmise, voici la syntaxe es6 -const instance = (token) => axios.create({ baseURL: `${config.API_URL}`, timeout: 1000, headers :{ 'authorization': 'Bearer ' + token } })
Jeet
18

En utilisant l'intercepteur Axios:

const service = axios.create({
  timeout: 20000 // request timeout
});

// request interceptor

service.interceptors.request.use(
  config => {
    // Do something before request is sent

    config.headers["Authorization"] = "bearer " + getToken();
    return config;
  },
  error => {
    Promise.reject(error);
  }
);
aneesh
la source
1
Est-ce le standard de la communauté pour configurer les en-têtes avec axios?
5ervant le
@ 5ervant J'ai passé un très mauvais moment en utilisant cette approche. C'était beaucoup de douleur et je ne le recommande donc pas.
ankush981
@ ankush981 qu'est-ce qui est si mauvais dans cette approche et laquelle recommandez-vous?
Nenad Kaevik le
1
@NenadKaevik Il y a un cas d'utilisation particulier que j'essayais de couvrir (interception de réponse): faire savoir à l'utilisateur quand le serveur dit 403 en réponse. Les gens mettent généralement l'étape de vérification du jeton pendant le chargement du composant, mais supposons que votre jeton ait été invalidé quelques secondes après sa vérification (pour une raison quelconque). Désormais, lorsque la personne clique sur un bouton, j'aimerais qu'elle sache qu'elle a été déconnectée. Il est difficile de faire cela en utilisant des intercepteurs car ils ajoutent un comportement global. Je suis entré dans une boucle de rechargement parce que l'intercepteur de demande ajoutait toujours le jeton et l'intercepteur de réponse redirigerait
ankush981
@NenadKaevik Donc, peut-être que le flux était difficile à atteindre ou que j'utilisais la mauvaise approche, mais depuis, j'ai en quelque sorte commencé à détester les intercepteurs.
ankush981
9

Si vous voulez des données après avoir passé le jeton dans l'en-tête, essayez ce code

const api = 'your api'; 
const token = JSON.parse(sessionStorage.getItem('data'));
const token = user.data.id; /*take only token and save in token variable*/
axios.get(api , { headers: {"Authorization" : `Bearer ${token}`} })
.then(res => {
console.log(res.data);
.catch((error) => {
  console.log(error)
});
Neel Patel
la source
2

Cela fonctionne et je n'ai besoin de définir le jeton qu'une seule fois dans mon app.js:

axios.defaults.headers.common = {
    'Authorization': 'Bearer ' + token
};

Ensuite, je peux faire des requêtes dans mes composants sans redéfinir l'en-tête.

"axios": "^0.19.0",

gdfgdfg
la source
Je ne sais pas pourquoi, mais de cette façon, cela ne fonctionne pas sur Safari sur un appareil iOS :(
ZecKa
0

axiosen lui-même vient avec deux «méthodes» utiles interceptorsqui ne sont que des middlewares entre la requête et la réponse. donc si à chaque demande vous souhaitez envoyer le token. Utilisez le interceptor.request.

J'ai fait un pack qui vous aide:

$ npm i axios-es6-class

Vous pouvez maintenant utiliser axios comme classe

export class UserApi extends Api {
    constructor (config) {
        super(config);

        // this middleware is been called right before the http request is made.
        this.interceptors.request.use(param => {
            return {
                ...param,
                defaults: {
                    headers: {
                        ...param.headers,
                        "Authorization": `Bearer ${this.getToken()}`
                    },
                }
            }
        });

      this.login = this.login.bind(this);
      this.getSome = this.getSome.bind(this);
   }

   login (credentials) {
      return this.post("/end-point", {...credentials})
      .then(response => this.setToken(response.data))
      .catch(this.error);
   }


   getSome () {
      return this.get("/end-point")
      .then(this.success)
      .catch(this.error);
   }
}

Je veux dire que la mise en œuvre du middlewaredépend de vous, ou si vous préférez créer votre propre axios-es6-class https://medium.com/@enetoOlveda/how-to-use-axios-typescript-like-a-pro-7c882f71e34a c'est le support poster d'où il vient

Ernesto
la source
-4

C'est ce à quoi j'ai également été confronté. Le jeton que vous passez n'est pas correct.

Il suffit de coder en dur le jeton et de le transmettre, vous obtiendrez la réponse correcte. Mais si le jeton n'est pas passé entre guillemets simples '', il échouera sûrement. Il doit être au format 'Autorisation': 'Porteur YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ', où après le porteur un espace doit être présent, également entre des guillemets simples très importants.

var token = "YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ";

var headers = {
  Authorization: "Bearer " + token,
  Accept: "application/json, text/plain, */*",
  "Content-Type": "application/json"
};

IMP: Le code ci-dessus fonctionnera Mais si vous publiez quelque chose comme:

'Autorisation': 'Bearer' + YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ, cela échouera

ou ----- le code ci-dessous échouera également, j'espère que vous comprenez la différence fondamentale

var token = YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjA0YmEzZmZjN2I1MmI4MDJkNQ;

var headers = {
  Authorization: "Bearer " + token,
  Accept: "application/json, text/plain, */*",
  "Content-Type": "application/json"
};
Athar
la source