These are some notes that I have needed to write down about using cookies in web applications. Admittedly, I don’t know a lot about cookies and should probably not be considered a source of authority on this topic.
Why cookies?
Making authenticated anchor tags
Can’t specify headers with <a>
tags.
Could supply token as query parameter, but that’s a security concern due to potential of token being cached with URL.
No need to manage JWTs within your application
Things that are annoying about JWTs when building frontend applications:
- You need to choose where to store the JWTs
- You need to supply the JWT to any code making API requests
How cookies?
Cookies are typically set by backend code after a user successfully logs in. They are typically signed to verify their authenticity. Often, they simply point to an identifier that tracks a user’s “session” within some stateful service (ie database).
How to do cross-origin cookies
- Backend must set the
access-control-allow-credentials
header to instruct browsers that it’s okay to pass credentials when making requests (docs). - Backend must specify the
access-control-allow-origin
header to instruct browsers which origins are allowed to access the API. Note that you can’t use * when passing credentials between origins (docs). - Backend will need to specify that our cookies have
samesite=none
if attempting to send cookie to other sites. Note thatSame-Site
is not the same asSame-Origin
, a cookie set withsamesite=strict
will still be passed between hosts at different subdomains or ports of a domain (docs). Also note thatSecure
must also be set whensamesite=none
(docs). - Backend must skip auth checks on preflight requests, as browsers don’t send cookies on
OPTIONS
requests (docs) - Frontend needs to provide credentials with requests.
1
await fetch(url, { credentials: true });