Como enviar cabeçalho de autorização com axios

96

Como posso enviar um cabeçalho de autenticação com um token via axios.js? Tentei algumas coisas sem sucesso, por exemplo:

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

Me dá este erro:

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

Consegui fazer funcionar definindo o padrão global, mas acho que essa não é a melhor ideia para uma única solicitação:

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

Atualização:

A resposta de Cole me ajudou a encontrar o problema. Estou usando o middleware django-cors-headers que já gerencia o cabeçalho de autorização por padrão.

Mas eu fui capaz de entender a mensagem de erro e corrigi um erro no meu código de solicitação do axios, que deve ser parecido com este

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

Respostas:

87

Em solicitações http não simples, seu navegador enviará uma solicitação de "comprovação" (uma solicitação do método OPTIONS) primeiro para determinar o que o site em questão considera informações seguras para enviar (veja aqui as especificações de política de origem cruzada sobre isso). Um dos cabeçalhos relevantes que o host pode definir em uma resposta de comprovação é Access-Control-Allow-Headers. Se algum dos cabeçalhos que você deseja enviar não estiver listado na lista de cabeçalhos da lista de permissões ou na resposta de comprovação do servidor, o navegador se recusará a enviar sua solicitação.

No seu caso, você está tentando enviar um Authorizationcabeçalho, o que não é considerado universalmente seguro para enviar cabeçalhos. O navegador então envia uma solicitação de comprovação para perguntar ao servidor se ele deve enviar esse cabeçalho. O servidor está enviando um Access-Control-Allow-Headerscabeçalho vazio (que significa "não permitir cabeçalhos extras") ou está enviando um cabeçalho que não inclui Authorizationem sua lista de cabeçalhos permitidos. Por causa disso, o navegador não enviará sua solicitação e, em vez disso, opta por notificá-lo emitindo um erro.

Qualquer solução alternativa de Javascript que você encontrar que permita enviar esta solicitação de qualquer maneira deve ser considerada um bug, pois é contra a política de solicitação de origem cruzada que seu navegador está tentando impor para sua própria segurança.

tl; dr - Se você quiser enviarAuthorizationcabeçalhos, é melhor seu servidor estar configurado para permitir isso. Configure seu servidor para que ele responda a umaOPTIONSsolicitação nesse url com umAccess-Control-Allow-Headers: Authorizationcabeçalho.

Cole Erickson
fonte
11
Obrigado, Cole! Sua resposta me ajudou a encontrar o problema. Estou usando o middleware django-cors-headers que já gerencia o cabeçalho de autorização por padrão. Mas eu consegui entender a mensagem de erro e consertei um erro no meu código de solicitação do axios, que deveria ser parecido com este return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
foobar
1
De nada! Eu encontro esse tipo de problema com minhas APIs o tempo todo. Estou feliz por ter ajudado você a entender o processo pelo qual ele deve passar.
Cole Erickson
43

Experimente isto:

axios.get(
    url,
    {headers: {
        "name" : "value"
      }
    }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );
Matija Župančić
fonte
1
Portanto, o nome do cabeçalho será 'Access-Control-Allow-Headers' e o valor é o que você deseja.
Matija Župančić
Então, você quer dizer que eu teria algo como: axios.get (url, {headers: {'Access-Control-Allow-Headers': 'Bearer <my token>'}})? Isso não funciona.
foobar
11
Eu acredito que deveria ser {'Autorização': 'Portador <meu token>'}
John Harding
35

Isso tem funcionado para mim:

let webApiUrl = 'example.com/getStuff';
let tokenStr = 'xxyyzz';
axios.get(webApiUrl, { headers: {"Authorization" : `Bearer ${tokenStr}`} });
sean717
fonte
Há menos detalhes na resposta em comparação com o anterior, mas esta é a resposta que todos procuram quando pesquisam no google.
Black Mamba
32

Em vez de adicioná-lo a todas as solicitações, você pode apenas adicioná-lo como uma configuração padrão.

axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` 
Canaan Etai
fonte
como você coloca essa configuração? na raiz (index.js, App.js)? Ou em um arquivo separado?
ibubi
8

Você está quase correto, apenas ajuste seu código desta forma

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

observe onde coloco os crases, adicionei '' após o Bearer, você pode omitir se tiver certeza de manipular no lado do servidor

Jalasem
fonte
6
Normalmente (por especificação) há um espaço, não um traço ( -), entre o esquema de autenticação e o token. Nunca vi nenhum tipo de servidor exigir um traço como você mostrou, e a maioria, senão todos, enviaria de volta um erro se um deles fosse fornecido.
Raman
6

Em vez de chamar a função axios.get, use:

axios({ method: 'get', url: 'your URL', headers: { Authorization: `Bearer ${token}` } })
Deepak
fonte
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: você deve adicionar OPÇÕES e autorização ao setHeader ()

esta mudança corrigiu o meu problema, experimente!

MESDOUR
fonte
0

Instale o corsmiddleware. Estávamos tentando resolvê-lo com nosso próprio código, mas todas as tentativas falharam terrivelmente.

Isso fez funcionar:

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

Link original

campainha
fonte
isso é para servidores de nó, não para axios
Marc Garcia
Os usuários que encontrarem esta pergunta podem achar esta resposta útil. Esta questão pode ser usada para trabalhar com servidores de nó em casos de uso e ser um lembrete de que os cors podem resolver seu problema ou para mover sua verificação de cabeçalho de backend abaixo do código acima. Ajudou a me salvar de tanta frustração, Obrigado campainha.
DORRITO
0

Você pode tentar isso.

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
fonte