0

Browser is ignoring reponse cookies (csrftoken + seesionid). document.cookie() returns empty string and chrome developer tool shows this site has no cookies

How to solve this ?

FRONT : Angular 2 (localhost:4200)

Back : Django/DRF (localhost:8000)

Login route : [post] /login

Response header :

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:4200
Allow:POST, OPTIONS
Date:Wed, 05 Apr 2017 07:38:24 GMT
Server:WSGIServer/0.2 CPython/3.5.2
Set-Cookie:sessionid=d5v1mri12bniyvyqqt55ar8mfl9mr2jk; expires=Wed, 19-Apr-2017 07:38:24 GMT; HttpOnly; Max-Age=1209600; Path=/
Set-Cookie:csrftoken=5PcTF8aQ1O79gdrylZcGchnmKyRy6zwS3kL2jR5dY2CMdjPfEYyhkoJjOzsDZuvj; expires=Wed, 04-Apr-2018 07:38:24 GMT; Max-Age=31449600; Path=/
Vary:Accept, Cookie, Origin
X-Frame-Options:SAMEORIGIN

Request header :

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,fr;q=0.6
Connection:keep-alive
Content-Length:51
content-type:application/json
Cookie:sessionid=d5v1mri12bniyvyqqt55ar8mfl9mr2jk; csrftoken=sml3uocRIeiB3KfHSnNkJXBJn3QAFN3p7lLtdvhrALgUwoVnfNjGM5PIy2L3UHls
Host:127.0.0.1:8000
Origin:http://localhost:4200
Referer:http://localhost:4200/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36
amine amine
  • 461
  • 5
  • 12

2 Answers2

2

Cookies are not shared among different ports of a host (localhost in your case). The browser shows you content from localhost:4200, but the cookies are set to localhost:8000. They are correctly set and used, as can be seen in your second listing titled "Request header". So to see them in the browser, you would have to open a URL from localhost:8000. Even then the sessionid would not be listed in document.cookie(), because it's marked as "HttpOnly" (which means not available to JavaScript).

Ján Halaša
  • 8,167
  • 1
  • 36
  • 36
  • ok for seesionid, what about csrftoken I need to access it (from :4200) using javascript to include it in the next request header, is this possible ? – amine amine Apr 05 '17 at 08:53
  • Cookies are included in requests automatically, so you don't need to access them in your scripts. See your request log - the csrftoken cookie is included there. – Ján Halaša Apr 05 '17 at 08:57
  • I need to do so to add CSRF token as header of request (not as cookie) this is how csrf prevension works. header key is called "X-CSRFToken" and is empty in my case which causes django to answer with 403 "missing csrf token or incorrect" – amine amine Apr 05 '17 at 09:00
  • Ah, yes, sorry. You cannot get the csrftoken cookie easily. The only way I can think of is probably opening an iframe and sending the token to the application (its parent frame) in an event. But this approach can be quite error prone. I think it's better to be sending CSRF as a cookie. See http://stackoverflow.com/questions/20504846/why-is-it-common-to-put-csrf-prevention-tokens-in-cookies – Ján Halaša Apr 05 '17 at 09:16
  • The iframe I mentioned would have to load a page from your backend. The page would contain just a script for sending the token on load and when the token changes. – Ján Halaša Apr 05 '17 at 09:27
  • I think it must be a solution a lot simpler to handle this. I am familiar with this issue. I used to have no problem in Angular 1, it only happened with Angular 2. I have two days working to figure it out, nothing concrete till now – amine amine Apr 05 '17 at 10:05
  • In AngularJS (1), did you have the frontend and backend served from different servers (ports)? If not, you could easily read the token. Now, you could get around it by configuring one of your servers to serve another one - e.g. node.js would re-route your backend somehow (just resending requests to/from the real backend). – Ján Halaša Apr 05 '17 at 10:10
  • Yes I had two different ports for Angular 1 too, I really can't understund what makes it different here – amine amine Apr 05 '17 at 10:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139961/discussion-between-amine-amine-and-jan-halasa). – amine amine Apr 05 '17 at 11:33
0

If you are use angular cli you could set proxy.

ng serve --proxy-config proxy.conf.json

sample of proxy.conf.json { "/api": { "target": "http://localhost:3000", "secure": false } }

Or local development use https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi

Kiss Robert
  • 201
  • 3
  • 7