Server-side HTTP FAQ: When you're writing a server-side application, are cookies considered to be part of the header information?
Answer
Yes, cookies are part of the HTTP headers. Specifically:
- When a server sends cookies to a client, they’re sent in the “Set-Cookie” response header
- When a client sends cookies back to the server, they’re included in the “Cookie” request header
As a brief aside, as you can infer from those two points, there is a difference between a *response header* and a *request header*.
Cookie/header example
For example, if you’re examining an incoming HTTP request in a server-side application, you’d find cookies in the header that look something like this:
Cookie: session_id=abc123; theme=dark
And when setting cookies from the server, you’ll send a header that looks like this:
Set-Cookie: session_id=abc123; Expires=Wed, 10 Dec 2024 10:18:14 GMT; Path=/
Each cookie is essentially (a) a key-value pair, with (b) optional attributes for things like expiration time, domain, path, and security flags (HttpOnly
, Secure
, SameSite
, etc.).
To add a bit more to this, this is how I create a cookie in a ZIO HTTP server-side application:
val COOKIE_SECRET = "secret"
val COOKIE_DOMAIN = Some("alvinalexander.com")
// cookie #1
val COOKIE_SESSION_NAME = "session_id"
val COOKIE_SESSION_VALUE = "abc1234567" // get from a data store
// cookie #2
val COOKIE_USER_PREFS_NAME = "user_prefs"
val COOKIE_USER_PREFS_VALUE = encodeCookieValue("theme=dark;lang=en")
// [1] this is a “Response Cookie”
private val sessionCookie = Cookie.Response(
name = COOKIE_SESSION_NAME, // cookie name
content = COOKIE_SESSION_VALUE, // cookie value
// domain = COOKIE_DOMAIN, // can’t do this in this demo
maxAge = Some(5.days) // cookie expiration
)
In my application, all cookies are also signed with this ZIO HTTP Middleware:
val run = Server
.serve(app @@ signCookies(COOKIE_SECRET))
.provide(Server.default)
The Middleware is the @@ signCookies
portion of that code.