如何使用axios发送授权头信息

149

我该如何通过 axios.js 发送带有令牌的身份验证头?我尝试了一些方法,但都没有成功,例如:

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

给我这个错误:

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

我通过设置全局默认值成功让它工作了,但是我猜想对于单个请求来说这不是最好的方案:


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

更新:

Cole的回答帮助我找到了问题所在。我正在使用django-cors-headers中间件,它已经默认处理授权标头。

但是我能够理解错误消息并修复了axios请求代码中的错误,应该像这样:

return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
12个回答

105
在非简单的http请求中,您的浏览器将首先发送一个"preflight"请求(OPTIONS方法请求),以确定该站点认为哪些信息是安全发送的(有关此内容,请参见这里的跨源策略规范)。主机可以在预检响应中设置的相关标头之一是Access-Control-Allow-Headers。如果您要发送的任何标头都没有列在规范中列出的白名单标头列表或服务器的预检响应中,则浏览器将拒绝发送您的请求。
在您的情况下,您正在尝试发送一个Authorization标头,它不被认为是通用安全发送标头之一。然后,浏览器会发送一个预检请求,询问服务器是否应该发送该标头。服务器要么发送一个空的Access-Control-Allow-Headers标头(被认为是“不允许任何额外的标头”),要么发送一个标头,其中不包括Authorization在其允许的标头列表中。因此,浏览器不会发送您的请求,而是选择通过抛出错误来通知您。
任何你发现的能够让你发送这个请求的JavaScript解决方法都应该被视为错误,因为它违反了浏览器试图实施的跨源请求策略,而这是为了保护你自己的安全。简而言之,如果你想发送"Authorization"头,你的服务器最好配置允许它。设置你的服务器响应那个URL上的"OPTIONS"请求,并带有一个"Access-Control-Allow-Headers: Authorization"头。

14
谢谢,Cole!你的回答帮助我找到了问题。我正在使用django-cors-headers中间件,它已经默认处理授权头部。但是我通过理解错误信息并修复axios请求代码中的错误,成功解决了问题。现在代码应该像这样:return axios.get(URLConstants.USER_URL, { headers: { Authorization: \Bearer ${data.token}` } });` - foobar
2
不客气!我在我的API中经常遇到这种问题。很高兴我能帮助你理解它必须经历的过程。 - Ashelyn Dawn
好吧,我整晚都在与这个axios跨域问题作斗争。如果我10小时前就找到了这个答案。 - anouar es-sayid

94

这对我很有效:

let webApiUrl = 'example.com/getStuff';
let tokenStr = 'xxyyzz';
axios.get(webApiUrl, { headers: {"Authorization" : `Bearer ${tokenStr}`} });

15
与上面的答案相比,这个答案的细节较少,但这正是每个人在搜索谷歌时都寻找的答案。 - Black Mamba

82

不必将它添加到每个请求中,您只需像以下示例一样将其添加为默认配置即可。

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

2
你会把这个配置放在哪里?是在根目录下(index.js,App.js)还是在一个单独的文件中? - ibubi
2
如果令牌还没有设置怎么办? - cikatomo
当代码准备好之后,您可以使用该代码进行导入,以便在请求之前使其可用。 - Canaan Etai

50

试一下:

axios.get(
    url,
    {headers: {
        "name" : "value"
      }
    }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );

1
因此,标头名称将是“Access-Control-Allow-Headers”,其值为您所需的内容。 - Matija Župančić
那么,你的意思是我会有这样的东西:axios.get(url,{headers:{'Access-Control-Allow-Headers':'Bearer <my token>'}})?那不起作用。 - foobar
12
我认为应该是 { 'Authorization': 'Bearer <我的令牌>' }。 - John Harding
1
第一条评论是不正确的;Access-Control-Allow-Headers是一个响应头,必须从服务器发送到浏览器。@JohnHarding是正确的;在请求中设置适当的标题是授权标题。此外,没有空格或其他特殊字符的标头不需要用引号括起来。由于问题特别涉及授权标头,并且这只提供了一般建议,仅通过“尝试此操作”进行解释,我不能以诚信的方式点赞它。 - Heretic Monkey

9
你的答案几乎正确,只需按照以下方式调整你的代码即可。
const headers = { Authorization: `Bearer ${token}` };
return axios.get(URLConstants.USER_URL, { headers });

请注意我放置反引号的位置,在Bearer之后,我添加了' ',如果您在服务器端处理时肯定可以省略。

6
通常(按规范),在认证方案和令牌之间使用空格,而不是破折号(-)。我从未见过任何类型的服务器需要像你展示的那样使用破折号,并且大多数(如果不是全部)会在提供破折号时返回错误。 - Raman

8

使用axios.get函数的替代方法:

axios({ method: 'get', url: 'your URL', headers: { Authorization: `Bearer ${token}` } })

1
这让我意识到我把主体放进了配置里。真是个新手错误。谢谢。 - Nate

4
const response=await axios(url,
    method:"GET"
    {
     headers: {
        "Authorization" : `Bearer ${token}`
      }
    })

虽然这段代码可能回答了问题,但提供有关它如何以及/或为什么解决问题的附加上下文将改善答案的长期价值。 - Donald Duck

3

你可以尝试这个。

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

2
创建一个新的axios实例来发送你的请求。
  const instance=axios.create({
    baseURL:'www.google.com/'
    headers:{
        'Content-Type':'application/json',
                    'Acess-Control-Allow-Origin':'*',
                    'Authorization':`Bearer ${token}`,
                    'Accept': "application/json"
        }
    })

await instance.get(url,data)

0
这是使用Postman的方式:
headers: {
    'Authorization': `Basic ${Buffer.from('username:password').toString('base64')}`
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接