Project Code:https://github.com/hyperlane-dev/hyperlane
Introduction
Cookie and session management are fundamental aspects of modern web development. They enable stateful interactions in the inherently stateless HTTP protocol, allowing servers to remember users across multiple requests. In the hyperlane framework, cookie handling is built directly into the request and response APIs, providing a clean and efficient way to manage user sessions.
This article covers everything you need to know about working with cookies in hyperlane — from reading incoming cookies to creating and sending new ones using the powerful CookieBuilder API.
Reading Cookies from Requests
Getting All Cookies
Hyperlane makes it easy to retrieve all cookies from an incoming HTTP request:
let cookies = ctx.get_request().try_get_cookies();
This returns all cookies sent by the client as part of the request. The try_get_cookies method parses the Cookie header and returns the cookie collection.
Getting a Specific Cookie
When you need to access a particular cookie by name, use:
let cookie = ctx.get_request().try_get_cookie("session_id");
This returns an Option type — Some(cookie_value) if the cookie exists, or None if it doesn't. This pattern encourages proper error handling and avoids panics from missing cookies.
Creating Cookies with CookieBuilder
Hyperlane provides a fluent CookieBuilder API for creating cookies with various attributes. The builder pattern allows you to chain configuration calls for a clean, readable syntax.
Basic Cookie Creation
let cookie = CookieBuilder::new("session_id", "abc123")
.set_path("/")
.http_only()
.build();
This creates a cookie named session_id with the value abc123, scoped to the root path and marked as HttpOnly (inaccessible to JavaScript, providing XSS protection).
Full Cookie Configuration
The CookieBuilder supports all standard cookie attributes:
let cookie = CookieBuilder::new("session", "token123")
.set_expires("Wed, 21 Oct 2025 07:28:00 GMT")
.set_domain("example.com")
.set_same_site("Strict")
.set_max_age(3600)
.set_path("/")
.secure()
.http_only()
.build();
Let's break down each attribute:
-
set_expires— Sets the cookie's expiration date in HTTP date format. After this date, the browser will no longer send the cookie. -
set_domain— Specifies which domain the cookie is valid for. The cookie will only be sent to the specified domain and its subdomains. -
set_same_site— Controls cross-site request behavior."Strict"prevents the cookie from being sent in cross-site requests, while"Lax"allows it for top-level navigations. -
set_max_age— Sets the cookie's lifetime in seconds. After this duration, the cookie expires. This is preferred overset_expiresas it is relative to the current time. -
set_path— Restricts the cookie to a specific URL path. The cookie is only sent for requests to paths under this prefix. -
secure()— Marks the cookie as secure, meaning it will only be sent over HTTPS connections. -
http_only()— Marks the cookie as HttpOnly, preventing access from JavaScript to mitigate XSS attacks.
Clearing Cookies
To delete a cookie from the client, create a new cookie with the same name but with an empty value and max_age of 0:
let clear_cookie = CookieBuilder::new("session", "")
.set_max_age(0)
.build();
This tells the browser to immediately expire the cookie, effectively removing it.
Sending Cookies in Responses
Once you have built a cookie, you attach it to the response using the Set-Cookie header:
let cookie = CookieBuilder::new("session_id", "abc123")
.set_path("/")
.http_only()
.build();
ctx.get_mut_response().set_header(SET_COOKIE, &cookie);
The SET_COOKIE constant is the standard header name for setting cookies. If you need to set multiple cookies, use add_header instead of set_header to append additional Set-Cookie headers:
ctx.get_mut_response().add_header(SET_COOKIE, &cookie1);
ctx.get_mut_response().add_header(SET_COOKIE, &cookie2);
Complete Session Management Example
Here is a complete example showing a login handler that creates a session cookie and a logout handler that clears it:
#[route("/login")]
struct LoginHandler;
impl ServerHook for LoginHandler {
async fn new(_: &mut Stream, _: &mut Context) -> Self {
Self
}
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Verify credentials (simplified for demonstration)
let body = ctx.get_request().get_body_string();
// Create a session cookie on successful authentication
let session_cookie = CookieBuilder::new("session_id", "abc123")
.set_path("/")
.http_only()
.secure()
.build();
ctx.get_mut_response()
.set_version(HttpVersion::Http1_1)
.set_status_code(200)
.set_header(SET_COOKIE, &session_cookie)
.set_body("Login successful");
let data = ctx.get_mut_response().build();
stream.try_send(data).await;
Status::Continue
}
}
#[route("/logout")]
struct LogoutHandler;
impl ServerHook for LogoutHandler {
async fn new(_: &mut Stream, _: &mut Context) -> Self {
Self
}
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Clear the session cookie
let clear_cookie = CookieBuilder::new("session_id", "")
.set_max_age(0)
.build();
ctx.get_mut_response()
.set_version(HttpVersion::Http1_1)
.set_status_code(200)
.set_header(SET_COOKIE, &clear_cookie)
.set_body("Logged out successfully");
let data = ctx.get_mut_response().build();
stream.try_send(data).await;
Status::Continue
}
}
Cookie-Based Authentication Middleware
You can combine cookie reading with authentication logic to create middleware that protects routes:
struct AuthMiddleware;
impl ServerHook for AuthMiddleware {
async fn new(_: &mut Stream, ctx: &mut Context) -> Self {
Self
}
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
let session_cookie = ctx.get_request().try_get_cookie("session_id");
match session_cookie {
Some(session_id) if !session_id.is_empty() => {
// Session exists — proceed to the next handler
Status::Continue
}
_ => {
// No valid session — reject the request
let data = ctx.get_mut_response()
.set_status_code(401)
.set_body("Unauthorized")
.build();
if stream.try_send(data).await.is_err() {
stream.set_closed(true);
}
Status::Reject
}
}
}
}
server.request_middleware::<AuthMiddleware>();
Session Management Best Practices
Always use
HttpOnlyfor session cookies. This prevents JavaScript access and mitigates XSS-based session theft.Use
Secureflag in production. Session cookies should only be transmitted over HTTPS to prevent interception.Set
SameSiteattribute. Use"Strict"or"Lax"to protect against CSRF attacks."Strict"provides the strongest protection but may affect user experience.Use
Max-Ageinstead ofExpires.Max-Ageis relative to the current time and avoids clock synchronization issues between server and client.Keep session identifiers unpredictable. Use cryptographically random values for session IDs rather than sequential or predictable values.
Implement proper session expiration. Set reasonable
Max-Agevalues and always clear cookies on logout by settingMax-Ageto 0.Scope cookies appropriately. Use
set_pathto limit cookie transmission to only the paths that need them.
Combining Cookies with Other Hyperlane Features
Cookies and Attributes
You can use hyperlane's attribute system to store session data that persists across multiple requests on the same connection:
ctx.set_attribute("user_id", "123");
let user_id: Option<String> = ctx.try_get_attribute("user_id");
Cookies and SSE
When working with Server-Sent Events, cookies set in the initial response are sent as part of the response headers:
let session_cookie = CookieBuilder::new("session_id", "abc123")
.set_path("/")
.http_only()
.build();
let data = ctx.get_mut_response()
.set_header(CONTENT_TYPE, TEXT_EVENT_STREAM)
.set_header(SET_COOKIE, &session_cookie)
.set_body(Vec::new())
.build();
stream.try_send(data).await;
Conclusion
Hyperlane provides a comprehensive and ergonomic API for cookie and session management. The CookieBuilder fluent interface makes it easy to create cookies with all standard attributes, while the request API provides safe methods for reading incoming cookies. By following best practices — using HttpOnly, Secure, and SameSite attributes — you can build secure session management systems that protect your users from common web vulnerabilities.
Whether you are building a simple login system or a complex multi-tenant application, hyperlane's cookie management tools give you everything you need to maintain stateful interactions in your web applications.
Project Code:https://github.com/hyperlane-dev/hyperlane
Top comments (0)