tower_sessions_cookie_store/
lib.rs

1//! Cookie-backed session persistence for `tower-sessions`.
2//!
3//! This crate provides a layer that inserts `tower_sessions_core::Session` into request
4//! extensions and persists the session record into a cookie.
5//!
6//! # Security
7//! The default format is a signed cookie (`signed` feature).
8//!
9//! The `dangerous-plaintext` feature enables a plaintext cookie controller. This offers **no tamper
10//! resistance** and should only be used for **testing and debugging**. Never enable or use this in
11//! a real application: a client can trivially edit the cookie to escalate privileges and
12//! impersonate other users (including staff/admin).
13//!
14//! ## Example (Axum, signed cookies)
15//!
16//! ```rust
17//! use axum::{routing::get, Router};
18//! use tower_sessions_cookie_store::{CookieSessionConfig, CookieSessionManagerLayer, Key, Session};
19//!
20//! async fn handler(session: Session) -> String {
21//!     let n: usize = session.get("n").await.expect("session get succeeds").unwrap_or(0);
22//!     session.insert("n", n + 1).await.expect("session insert succeeds");
23//!     format!("n={n}")
24//! }
25//!
26//! let key = Key::generate();
27//! let config = CookieSessionConfig::default().with_secure(false);
28//! let app = Router::<()>::new()
29//!     .route("/", get(handler))
30//!     .layer(CookieSessionManagerLayer::signed(key).with_config(config));
31//! ```
32
33#[cfg(all(
34    feature = "key-expansion",
35    not(any(feature = "signed", feature = "private"))
36))]
37compile_error!("feature `key-expansion` requires `signed` and/or `private`.");
38
39mod config;
40mod controller;
41pub mod format;
42/// Tower layer for cookie-backed sessions.
43pub mod layer;
44mod store;
45
46pub use tower_cookies::cookie::SameSite;
47pub use tower_sessions_core::{Session, session::Expiry, session_store};
48
49#[cfg(any(feature = "signed", feature = "private"))]
50pub use tower_cookies::Key;
51
52pub use crate::config::CookieSessionConfig;
53pub use crate::config::DEFAULT_COOKIE_NAME;
54pub use crate::controller::CookieController;
55pub use crate::format::{decode_record, encode_record};
56pub use crate::layer::CookieSessionManagerLayer;
57
58#[cfg(feature = "signed")]
59pub use crate::controller::SignedCookie;
60
61#[cfg(feature = "private")]
62pub use crate::controller::PrivateCookie;
63
64#[cfg(feature = "dangerous-plaintext")]
65pub use crate::controller::DangerousPlaintextCookie;