Crates.io | tower-sessions-ext |
lib.rs | tower-sessions-ext |
version | 1.0.0 |
created_at | 2025-06-15 19:59:26.060043+00 |
updated_at | 2025-09-09 17:18:48.997253+00 |
description | A maintained fork of tower-sessions-ext, providing session middleware for tower and axum. |
homepage | https://github.com/sagoez/tower-sessions-ext |
repository | https://github.com/sagoez/tower-sessions-ext |
max_upload_size | |
id | 1713595 |
size | 158,080 |
🥠Sessions as a `tower` and `axum` middleware.
This crate provides sessions, key-value pairs associated with a site
visitor, as a tower
middleware.
It offers:
SessionStore
trait, fully decoupling sessions from their
storage.axum
Extractor for Session
: Applications built with axum
can use Session
as an extractor directly in their handlers. This makes
using sessions as easy as including Session
in your handler.Serialize
and can
be converted to JSON, it's straightforward to insert, get, and remove any
value.This crate's session implementation is inspired by the Django sessions middleware and it provides a transliteration of those semantics.
This crate is a maintained fork of the original tower-sessions
project. We extend our sincere gratitude to Max Countryman and all the original contributors for their foundational work and excellent design that made this project possible.
Session data persistence is managed by user-provided types that implement
SessionStore
. What this means is that applications can and should
implement session stores to fit their specific needs.
That said, a number of session store implementations already exist and may be useful starting points.
Crate | Persistent | Description |
---|---|---|
tower-sessions-ext-sqlx-store |
Yes | SQLite, Postgres, and MySQL session stores |
Have a store to add? Please open a PR adding it.
To use the crate in your project, add the following to your Cargo.toml
file:
[dependencies]
tower-sessions-ext = "1.0.0"
axum
Exampleuse std::net::SocketAddr;
use axum::{response::IntoResponse, routing::get, Router};
use serde::{Deserialize, Serialize};
use time::Duration;
use tower_sessions_ext::{Expiry, MemoryStore, Session, SessionManagerLayer};
const COUNTER_KEY: &str = "counter";
#[derive(Default, Deserialize, Serialize)]
struct Counter(usize);
async fn handler(session: Session) -> impl IntoResponse {
let counter: Counter = session.get(COUNTER_KEY).await.unwrap().unwrap_or_default();
session.insert(COUNTER_KEY, counter.0 + 1).await.unwrap();
format!("Current count: {}", counter.0)
}
#[tokio::main]
async fn main() {
let session_store = MemoryStore::default();
let session_layer = SessionManagerLayer::new(session_store)
.with_secure(false)
.with_expiry(Expiry::OnInactivity(Duration::seconds(10)));
let app = Router::new().route("/", get(handler)).layer(session_layer);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
axum::serve(listener, app.into_make_service())
.await
.unwrap();
}
You can find this example as well as other example projects in the example directory.
[!NOTE] See the crate documentation for more usage information.
This crate uses #![forbid(unsafe_code)]
to ensure everything is implemented in 100% safe Rust.
We appreciate all kinds of contributions, thank you!