I don't understand cookie parsing back into a cookie string or cookies header that's sent to browser. Every stack overflow question mentions platform-specific solution while I am trying to go low level.
Alright so here's an example cookie string fetched from a login request:
AWSELB=1fff5a66839f6934cf8dab76e45ffa97; Path=/,
jses_WS40=02668ebd-0715-46f1-8ddf-97acfe1a28e9; path=/; Secure;
HttpOnly,
AuthToken=EFKFFFCH#K#GHIHEJCJMMGJM>CDHDEK>CFGK?MHJ>>JI#B??#CAEHBJH#H#A#GCFDLIMLJEEJEIFGALA?BIM?#G#DEDI#JE?I?HKJBIDDHJMEFEFM>G#J?I??B#C>>LAH?GCGJ#FMEGHBGAF;
expires=Sun, 31-Jan-2021 01:58:50 GMT; path=/; Secure; HttpOnly,
FirstReferrer=; expires=Fri, 31-Jan-2020 20:10:30 GMT; path=/
It should produce following cookies:
AWSELB, jses_WS40, AuthToken, FirstReferrer
But how should I parse it back? What's the format? I can't find it anywhere.
Related
Source
Cookies are placed on the device used to access a website, and more than one cookie may be placed on a user’s device during a session.
As I see, one site can work with more than 1 cookie file. And I don't understand the mechanism of this. What do I mean? I realize that one HTTP response can contain several set-cookie that "tell" browser to save needed cookie on the client's device. For example:
Cookies are set using the Set-Cookie header field, sent in an HTTP response from the web server. This header field instructs the web browser to store the cookie and send it back in future requests to the server (the browser will ignore this header field if it does not support cookies or has disabled cookies).
set-cookie: _hexlet_session2=AiUPd6RFbcrnoGnZSLAYSBzdJqxsQ4sTc%2BW0xXuOKzlenyv5GwkkbpdkD6IVDybDlD8vQcOcgGax98%2FmzIBJrz9f%2BDIJxWRpknZsRSfBXuC9yRfndovBUG6w4fTql4qp7zPozd2veFDLOU4koPVYiUQxgBLM6NkyYg%2Bhs%2BQe%2FSZezleVgMBVD%2FFC070DjV7t2eN01o26kcbd0pQsf9k1LE4JN0aDzSxu8elxLyAWkIJ5l3m%2BcI%2BpgOxk87Uwh9WdTHVuDaraiRaVJz1aZq5hr%2FgzaZiK%2Bgi6ChX60nhha1an610b1v3EE7xgkEM332uFPU0w675fHEr4APTdPDVtJRa3--qQi0cqcljC8i4klD--fXTErw9bhX7%2Fd1xfPE4Gww%3D%3D; domain=.hexlet.io; path=/; expires=Sun, 16 Aug 2020 03:38:11 GMT; secure; HttpOnly; SameSite=Lax
set-cookie: GCLB=CLTE8bzdlaS6Zg; path=/; HttpOnly; expires=Thu, 16-Jul-2020 03:39:50 GMT
But I still can't get how this transmission mechanism works. I've read before that every cookie has its own session id. As I understand (maybe I'm wrong), <cookie-name>=<cookie-value> is responsible for indication session id. It doesn't matter what kind of cookie is send, every cookie has its own <cookie-name>=<cookie-value>. For example, from MDN:
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
And... when cookie file is send to the server, its session id is searched on the server. When it's finally found, client can get all needed data. That's quite understandable.
But there's something I don't understand. Like I said before, every cookie file has its own session id. When HTTP request is send to the server with several cookies, are all session IDs searched on the server? How does it happen?
And... The main question: how can one request have many session IDs? I mean, for this reason we can't login with 2 different accounts in 1 browser. One client (it's browser in most cases) can have just one session id on some server.
Could someone explain me in a nutshell how server works with multiple cookies?
A website may need to store multiple pieces of information about a user, not only the session. Maybe there is a preference that you don't want to save to the backend and need to be different for each session.
e.g.
A user could have to select a language when he login in or a font size in settings.
Set-Cookie: language=en
Set-Cookie: font_size=16px
Set-Cookie: sessionid=4324324324233
That way the server will know what response to give at future requests(maybe the server is rendering a part of the site and needs to know the font_size and language before the response).
I have never seen multi-sessions on one server, and I don't see any reason.
Issue:
Cookie set between server.com and CLIENT is not being passed to a CNAME server: abc.server.com.
User's Flow:
CLIENT sends GET request for page data # request URL dev.server.com/myapi for a website that runs on https://abc.mywebsite.com
dev.server.com responds with:
Set-Cookie: MYCOOKIE=asdfasdf1; expires=Tue, 04 May 2021 06:59:32 GMT; domain=.server.com; path=/; SameSite = None; secure; httponly
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://mywebsite.com
Referrer-Policy: strict-origin
On the CLIENT's browser: client makes a POST to a CNAME my-cname-host.server.com
Why isn't the cookie being passed onto this last POST request? It seems domain= is set properly to include the CNAME.
I have set all headers that I know of to disable caching (even disabling ETAG) on my server, yet Safari still occasionally (about 50% times) caches my requests.
Workflow
I am implementing oauth 1, so:
Browser makes GET /api/user request
Server returns 405
Browser redirects to 3rd party website to authenticate
Browser is redirected to api/callback which stores some info into cookie.
Browser is redirected back to original route.
Browser makes GET /api/user request which should be successful, however it gets 405 served from disk cache instead.
Request summary from Safari Network Inspector
Summary
URL: http://localhost:3000/api/user
Status: 405 Method Not Allowed
Source: Disk Cache
Request
No request, served from the disk cache.
Response
Transfer-Encoding: Identity
Content-Type: application/json; charset=utf-8
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0
Vary: Cookie, Accept-Encoding
Date: Wed, 23 Jan 2019 11:34:23 GMT
Content-Encoding: gzip
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Connection: close
x-powered-by: Express
Conclusion
I have no idea what's wrong and I will greatly appreciate any help. My
Safari version is 12.0.2. I wasn't able to replicate this issue with Chrome.
Use Vary: *. This magically solved my problem.
This answer helped me: https://stackoverflow.com/a/2068353/1364158
Alternatively, you can really force browser to load a new version of request by including some meaningless random query arg in your url, e.g. /api/user?ts=18284
Given this server response:
HTTP/1.1 200 OK
Date: Fri, 23 Mar 2018 12:17:57 GMT
Access-Control-Allow-Origin: http://localhost:8888
Vary: Origin
Access-Control-Allow-Credentials: true
Set-Cookie: key=value;Version=1
Content-Type: application/json
Content-Length: 276
I thought this cookie (key=value) would be stored on client side and I would be able to view it from Chrome DevTools. However I don't see any cookie there. And the cookie is not included on the further requests made after the requested shown above. So I guess it's not stored.
To store the cookies is not the default behavior of the browser?
I've tried setting the cookie property httpOnly to true with the same results.
How can force the browser to store the cookie without using JS and including it on further requests without any JS interaction?
I'm setting a few cookies from PHP and they're being sent back to my browser, but this is what's being returned. From what I can tell, there's a comma present that should be a semi-colon. This wouldn't bother me if the browser was setting any cookies, but it isn't so I figure this is the issue. Here's the Set-Cookie string:
PHPSESSID=stringhere; path=/, cookie1=stringhere; expires=Thu, 02-Aug-2012 06:50:32 GMT; path=/; domain=example.com; httponly, cookie2=stringhere; expires=Thu, 02-Aug-2012 06:50:33 GMT; path=/; domain=example.com
The first comma is the one I'm talking about.
Edit: Note the PHPSESSID cookie does get set.