Enviando o token do portador com axios

118

No meu aplicativo de reação, estou usando axios para executar as solicitações da API REST.

Mas não é possível enviar o cabeçalho de autorização com a solicitação.

Aqui está o meu código:

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

Aqui, o validToken()método simplesmente retornaria o token do armazenamento do navegador.

Todas as solicitações estão tendo uma resposta de 500 erros dizendo que

O token não pôde ser analisado a partir da solicitação

do back-end.

Como enviar o cabeçalho de autorização com cada solicitação? Você recomendaria qualquer outro módulo com react?

rakibtg
fonte
Eu não acho que seja um axiosproblema. verifique o seu validToken()funcionamento, ele está retornando algo que o seu servidor não entende.
xiaofan2406
Verifiquei
novamente

Respostas:

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

O primeiro parâmetro é o URL.
O segundo é o corpo JSON que será enviado junto com sua solicitação.
O terceiro parâmetro são os cabeçalhos (entre outras coisas). Que é JSON também.

Médico
fonte
4
Você perdeu um espaço entre o portador e o token - então funcionará.
dez
Postagem do médico: "chave:" valor "tem uma citação que deve ser removida ... Mas corrigir isso fez com que o auth funcionasse para meu aplicativo
react
1
@mediaguru Thx pelo comentário. Eu consertei (suponho)! A citação deve ter sido introduzida por alguém editando a resposta ...
Doutor
2
Bearerdeve ser usado com B maiúsculo, não é?
Alizadeh118
1
@ Alizadeh118 Sim, de acordo com a especificação HTTP. Mas muitas APIs não insistem na capitalização correta.
OneHoopyFrood
60

Esta é uma maneira única de definir o token de autorização em axios. Definir a configuração para cada chamada do axios não é uma boa ideia e você pode alterar o token de autorização padrão:

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

Editar , graças a Jason Norwood-Young.

Algumas APIs exigem que o portador seja escrito como Portador, então você pode fazer:

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

Agora você não precisa definir a configuração para cada chamada de API. Agora o token de autorização é definido para cada chamada axios.

Ilyas karim
fonte
18
Bearerprecisa ser capitalizado para algumas APIs (descobri da maneira mais difícil).
Jason Norwood-Young
23

Você pode criar uma configuração uma vez e usá-la em qualquer lugar.

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
fonte
De onde está o valor do token passado neste exemplo? Para meu aplicativo, o token seria passado de volta para a api no cabeçalho ou no corpo após um login bem-sucedido.
Ken
está aquiheaders: {'Authorization': 'Bearer '+token}
M.suleman Khan
Como transmitir dados se for uma solicitação POST
M.suleman Khan
Para aqueles que estão se perguntando de onde o valor do token pode ser passado, aqui está a sintaxe es6 -const instance = (token) => axios.create({ baseURL: `${config.API_URL}`, timeout: 1000, headers :{ 'authorization': 'Bearer ' + token } })
Jeet
18

Usando o interceptor 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
fonte
1
Este é o padrão da comunidade para configurar os cabeçalhos com axios?
servo
@ 5ervant Eu tive uma experiência muito feia usando essa abordagem. Foi muita dor e não recomendo.
ankush981
@ ankush981 o que há de tão ruim nessa abordagem e qual você recomenda?
Nenad Kaevik
1
@NenadKaevik Há um caso de uso específico que eu estava tentando cobrir (interceptação de resposta): permitir que o usuário saiba quando o servidor diz 403 em resposta. As pessoas geralmente colocam a etapa de verificação do token durante o carregamento do componente, mas suponha que seu token foi invalidado alguns segundos depois de ser verificado (por qualquer motivo). Agora, quando a pessoa clica em um botão, gostaria que ela soubesse que foi desconectada. É difícil fazer isso usando interceptores, pois eles adicionam comportamento global. Entrei em um loop de recarregamento porque o interceptor de solicitação sempre adicionaria o token e o interceptor de resposta redirecionaria
ankush981
@NenadKaevik Então, talvez o fluxo fosse difícil de alcançar ou eu estivesse usando a abordagem errada, mas desde então comecei a odiar interceptadores.
ankush981
9

Se você quiser alguns dados depois de passar o token no cabeçalho, tente este código

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
fonte
2

Isso funciona e eu preciso definir o token apenas uma vez em app.js:

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

Então, posso fazer solicitações em meus componentes sem definir o cabeçalho novamente.

"axios": "^0.19.0",

gdfgdfg
fonte
Não sei por que, mas dessa forma não funciona no Safari no dispositivo iOS :(
ZecKa
0

axiospor si só vem com dois "métodos" úteis, interceptorsque não são nada além de middlewares entre a solicitação e a resposta. então, se em cada solicitação você deseja enviar o token. Use o interceptor.request.

Eu fiz um pacote que ajuda você:

$ npm i axios-es6-class

Agora você pode usar axios como 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);
   }
}

Quero dizer, a implementação do middlewaredepende de você, ou se você preferir criar seu próprio axios-es6-class https://medium.com/@enetoOlveda/how-to-use-axios-typescript-like-a-pro-7c882f71e34a , é o meio postar de onde veio

Ernesto
fonte
-4

Isso é o que eu também enfrentei. O token que você está passando não está correto.

Apenas codifique o token e passe, você obterá a resposta correta. Mas se o token não for passado em aspas simples '', ele certamente falhará. Deve estar no formato 'Authorization': 'Bearer YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ', onde após o Bearer um espaço deve estar presente, também está presente entre aspas simples.

var token = "YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ";

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

IMP: O código acima funcionará, mas se você postar algo como:

'Autorização': 'Portador' + YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ, irá falhar

ou ----- o código abaixo também falhará, espero que você entenda a diferença básica

var token = YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjA0YmEzZmZjN2I1MmI4MDJkNQ;

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