4

I have an application where the Vue front-end is on a different domain than the server. Specifically, Vue is located on localhost:8080 and the server is located on localhost:4000.

During successful logins, the server responds with an HttpOnly cookie that has a session key. Here's the response:

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

However, subsequent requests made with Vue Resource don't send this cookie back to the server, even though I'm including the credentials: true option:

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

I know the credentials aren't included because I can see the request header in 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

As such, I get a 401 Unauthorized response from the server.

Do I need to do something special to have this cookie sent back to the server during requests?

Update 1: Also tried with axios, using withCredentials: true. Same result.

Update 2: Upon further examination, this seems to be because the browser does not save the cookie for some reason, despite the fact that it arrives with the response. Maybe the fact that it's a single-page application has to do with this. I guess this brings up the question though: how to use session cookies with SPAs?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Ege Ersoz
  • 6,461
  • 8
  • 34
  • 53
  • `Vue.prototype.$http = axios.create({ withCredentials: true });` should be what you need. Is this how you're specifying it? – thanksd Mar 16 '17 at 15:47
  • I do this with axios: `this.axios.create({withCredentials: true}).get("http://localhost:4000/api/account/").then(...)` – Ege Ersoz Mar 16 '17 at 18:33
  • 1
    If your server is sending a set-cookie header, this should be managed by the browser itself. The only thing that might be causing this issue here is that you are not on the same domain. Try to set virtual hosts with a dummy domain name for both frontend and backend and see if it works. – Deepak Mar 20 '17 at 10:49
  • Yes, this was actually the issue. I forgot to post it as an answer. Thanks for reminding me. – Ege Ersoz Mar 20 '17 at 18:28

1 Answers1

7

Figured it out. Two issues. First, the cookie was arriving at the browser with domain localhost but I was actually making the requests to a dummy domain that I had simply mapped to localhost. Because the domains didn't match, the browser didn't send the cookie.

Second, here is the correct way to use the withCredentials option in Axios:

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

Setting the option inside the request itself didn't work for some reason.

Ege Ersoz
  • 6,461
  • 8
  • 34
  • 53