In a server-side application, are cookies considered to be part of the header information?

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:

  1. When a server sends cookies to a client, they’re sent in the “Set-Cookie” response header
  2. 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.