无法在 CORS 请求中发送凭据

Unable to send credentials in CORS request

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

在成功登录期间,服务器使用具有 session 键的 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:

中看到请求 header
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: 还尝试使用 axios,使用 withCredentials: true。同样的结果。

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

想通了。两个问题。首先,cookie 到达域为 localhost 的浏览器,但我实际上是在向我简单映射到本地主机的虚拟域发出请求。因为域不匹配,浏览器没有发送 cookie。

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

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

出于某种原因,在请求本身内设置选项无效。