Skip to main content

Cookie

ZIO HTTP has special support for Cookie headers using the Cookie Domain to add and invalidate cookies. Adding a cookie will generate the correct Set-Cookie headers

Cookie can be created with params name, content, expires, domain, path, isSecure, isHttpOnly, maxAge, sameSite and secret according to HTTP Set-Cookie

The below snippet creates a cookie name as id and content as abc with default params.

 val cookie: Cookie = Cookie("id", "abc")
  • withContent updates the content of cookie
 val newCookie = cookie.withContent("def")
  • withExpiry updates the expiration date of cookie
 val newCookie = cookie.withExpiry(Instant.MAX)
  • withMaxAge updates the max-age of the cookie
 val newCookie = cookie.withMaxAge(5 days)
  • withDomain updates the host to which the cookie will be sent
 val newCookie = cookie.withDomain("example.com")
  • withPath updates the path of the cookie
 val newCookie = cookie.withPath(!! / "cookie")
  • withSecure enables cookie only on https server
 val newCookie = cookie.withSecure
  • withHttpOnly forbids JavaScript from accessing the cookie
 val newCookie = cookie.withHttpOnly
  • withSameSite updates whether or not a cookie is sent with cross-origin requests
 val newCookie = cookie.withSameSite(Instant.MAX)

you can reset cookie params using:

  • withoutSecure resets isSecure to false in cookie
  • withoutHttpOnly resets isHttpOnly to false in cookie
  • withoutExpiry resets expires to None
  • withoutDomain resets domain to None
  • withoutPath resets path to None
  • withoutMaxAge resets maxAge to None
  • withoutSameSite resets sameSite to None

The cookies can be signed with a signature:

  • Using sign To sign a cookie, you can use sign
 val cookie = Cookie("key", "hello").withMaxAge(5 days)
val app = Http.collect[Request] { case Method.GET -> !! / "cookie" =>
Response.ok.addCookie(cookie.sign("secret"))
}
  • Using signCookies middleware

To sign all the cookies in your HttpApp, you can use signCookies middleware:

  private val cookie = Cookie("key", "hello").withMaxAge(5 days)
private val app = Http.collect[Request] {
case Method.GET -> !! / "cookie" => Response.ok.addCookie(cookie)
case Method.GET -> !! / "secure-cookie" => Response.ok.addCookie(cookie.withSecure)
}

// Run it like any simple app
override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] =
Server.start(8090, app @@ signCookies("secret")).exitCode

The cookies can be added in Response headers:

 val cookie1: Cookie = Cookie("id", "abc")
val res = Response.ok.addCookie(cookie1)

It updates the response header Set-Cookie as

Set-Cookie: <cookie-name>=<cookie-value>

In HTTP requests, cookies are stored in the cookie header. cookiesDecoded can be used to get all the cookies in the request.

 private val app = Http.collect[Request] {
case req @ Method.GET -> !! / "cookie" =>
Response.text(req.cookiesDecoded.mkString(""))
}