无法在CORS请求中发送凭据

时间:2017-03-15 22:46:21

标签: cors vue.js vuejs2 axios vue-resource

我有一个应用程序,其中Vue前端与服务器位于不同的域。具体来说,Vue位于localhost:8080,服务器位于localhost:4000

在成功登录期间,服务器使用具有会话密钥的HttpOnly cookie进行响应。以下是回复:

HTTP/1.1 200 OK
server: Cowboy
date: Wed, 15 Mar 2017 22:35:46 GMT
content-length: 59
set-cookie: _myapp_key=SFMyNTY.g3QAAAABbQAAABBndWFyZGlhbl9kZWZhdWx0bQAAAUNleUpoYkdjaU9pSklVelV4TWlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKaGRXUWlPaUpWYzJWeU9qSWlMQ0psZUhBaU9qRTBPVEl5TURrek5EY3NJbWxoZENJNk1UUTRPVFl4TnpNME55d2lhWE56SWpvaVFYTndhWEpsSWl3aWFuUnBJam9pWWpreU5tVmpZek10TVRrM1lTMDBPREkyTFRrek5tSXRaRGxsTURneE5UUTNZVEpsSWl3aWNHVnRJanA3ZlN3aWMzVmlJam9pVlhObGNqb3lJaXdpZEhsd0lqb2lZV05qWlhOekluMC43THdySDUxb1hVVFR3OEhYMzBPWDJTeTd0Si05RTFFZEpQV3ZDLS1WU3YycllpZ29aTUY4NkhUMzB6Q29SWXFBajlxYXFQc0dqTzNNNFJyOHYyY1ZGZw.2k1A4HuW6VV8ACZhgHY6Szuf5gXKAe_QwMCN3doi9D4; path=/; HttpOnly
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate
x-request-id: qi2q2rtt7mpi9u9c703tp7idmfg4qs6o
access-control-allow-origin: http://localhost:8080
access-control-expose-headers: 
access-control-allow-credentials: true
vary: Origin

但是,使用Vue Resource发出的后续请求不会将此Cookie发送回服务器,即使我包含credentials: true选项:

this.$http.get("http://localhost:4000/api/account/", {credentials: true}).then(response => {
  //do stuff
}, response => {
  console.log(response.body.error)
})

我知道凭据没有包含在内,因为我可以在Chrome中看到请求标头:

GET /api/account/ HTTP/1.1
Host: localhost:4000
Connection: keep-alive
Accept: application/json
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,tr;q=0.6

因此,我从服务器收到401 Unauthorized响应。

我是否需要做一些特殊的事情才能在请求期间将此cookie发送回服务器?

更新1:还使用withCredentials: true尝试了axios。结果相同。

更新2:经过进一步检查,这似乎是因为浏览器由于某种原因没有保存cookie,尽管它随响应一起到达。也许它是单页应用程序的事实与此有关。我想这提出了一个问题:如何使用SPA的会话cookie?

1 个答案:

答案 0 :(得分:5)

想出来。两个问题。首先,cookie使用域localhost到达浏览器,但我实际上是向虚拟域发出请求,我只是映射到localhost。由于域名不匹配,浏览器不会发送cookie。

其次,这是在Axios中使用withCredentials选项的正确方法:

axios.create({withCredentials: true}).get(/* ... */)

在请求中设置选项本身由于某种原因不起作用。