Cookies
Volga provides full support for cookies through seamless integration with the cookie
crate. This guide explains how to enable and use cookie functionality in your application, including basic usage, customization, and secure (signed and private) cookies.
Enabling Cookie Support
To use cookies in your app, you need to enable the appropriate feature flags in your Cargo.toml
. If you're not using the full
feature set, add the cookie
feature manually:
[dependencies]
volga = { version = "0.5.8", features = ["cookie"] }
# Optional: explicitly depend on the cookie crate
cookie = "0.18.1"
For signed or private cookies, see the Signed & Private Cookies section.
Basic Usage
Here's how to create and read cookies:
use volga::{
App, HttpResult,
http::Cookies,
headers::{Header, Authorization},
error::Error,
status, ok, see_other
};
async fn login(cookies: Cookies, auth: Header<Authorization>) -> Result<(HttpResult, Cookies), Error> {
let session_id = authorize(auth)?;
Ok((see_other!("/me"), cookies.add(("session-id", session_id))))
}
async fn me(cookies: Cookies) -> HttpResult {
if cookies.get("session-id").is_some() {
ok!("Success")
} else {
status!(401, "Unauthorized")
}
}
fn authorize(auth: Header<Authorization>) -> Result<String, Error> {
// Dummy implementation. Replace with your own logic.
Ok("generated-session-id".to_string())
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
app.map_post("/login", login);
app.map_get("/me", me);
app.run().await
}
Notes:
- The
Cookies
extractor handles reading fromCookie
headers and automatically setsSet-Cookie
headers for responses. - You can chain multiple cookie additions using
.add(...)
.
Creating Secure Cookies
For secure or customized cookies (e.g., HttpOnly
, Secure
, custom domain/path), use the CookieBuilder
:
use cookie::{Cookie, time::Duration};
let cookie = Cookie::build(("session-id", session_id))
.domain("www.example.org")
.path("/")
.secure(true)
.http_only(true)
.max_age(Duration::days(1))
.build();
cookies.add(cookie);
Tips
Cookie::build(...)
takes either a name/value tuple or just a name, depending on your needs.
Reading Cookies
To access a cookie by name:
if let Some(cookie) = cookies.get("session-id") {
println!("Session ID: {}", cookie.value());
}
Signed & Private Cookies
To protect cookie integrity or privacy, Volga supports two secure cookie modes:
Type | Use Case | Crate Feature | API |
---|---|---|---|
Signed | Detect tampering (readable) | signed-cookie | SignedCookies |
Private | Tamper-proof and encrypted (hidden) | private-cookie | PrivateCookies |
Enable Secure Cookie Support
Update your Cargo.toml
to include the desired feature and the DI system (di
):
# For signed cookies
volga = { version = "0.5.8", features = ["signed-cookie", "di"] }
# For private cookies
volga = { version = "0.5.8", features = ["private-cookie", "di"] }
# For all cookies features
volga = { version = "0.5.8", features = ["cookie-full", "di"] }
Register Secret Keys
Signed and private cookies require secret keys, provided via DI:
use volga::http::SignedKey;
app.add_singleton(SignedKey::generate()); // or use your own key
Alternatively, for private cookies:
use volga::http::PrivateKey;
app.add_singleton(PrivateKey::generate()); // or use your own key
Once registered, you can extract SignedCookies
or PrivateCookies
just like Cookies
.
Best Practices
- Use
HttpOnly
andSecure
flags for session or authentication cookies to prevent XSS and eavesdropping. - Set a
SameSite
policy (viacookie::CookieBuilder
) for cross-site protection. - Rotate signing/encryption keys periodically if you use
SignedCookies
orPrivateCookies
. - Avoid storing sensitive data directly in cookies unless encrypted via private cookies.