Expand description
§Overview
Simple, extensible session library for Rocket applications.
- Session cookies are securely stored and encrypted using Rocket’s built-in private cookies
- Session guard can be used multiple times during a request, enabling various layers of authentication and authorization through Rocket’s request guard system.
- Makes use of Rocket’s request-local cache to ensure that only one backend call will be made to get the session data, and if the session is updated multiple times during the request, only one call will be made at the end of the request to save the session.
- Multiple storage providers available, or you can use your own session storage by implementing the SessionStorage trait.
§Usage
While technically not needed for development, it is highly recommended to set the secret key in Rocket. That way the sessions will stay valid after reloading your code if you’re using a persistent storage provider. The secret key is required for release mode.
§Basic setup
use rocket::routes;
use rocket_flex_session::{Session, RocketFlexSession};
// Create a session data type (this type must be thread-safe and Clone)
#[derive(Clone)]
struct MySession {
user_id: String,
// ..other session fields
}
#[rocket::launch]
fn rocket() -> _ {
rocket::build()
// attach the `RocketFlexSession` fairing, passing in your session data type
.attach(RocketFlexSession::<MySession>::default())
.mount("/", routes![login])
}
// use the `Session` request guard in a route handler
#[rocket::post("/login")]
fn login(mut session: Session<MySession>) {
session.set(MySession { user_id: "123".to_owned() });
}
§Request guard auth
If a valid session isn’t found, the Session request guard will still succeed, but calling Session.get()
or Session.tap() will yield None
- indicating an empty/uninitialized session.
This primitive is designed for you to be able to add your authentication and authorization layer on
top of it using Rocket’s flexible request guard system.
For example, we can write a request guard for our MySession
type, that will attempt to retrieve the
session data and verify whether there is an active session:
use rocket::{
http::Status,
request::{FromRequest, Outcome},
Request,
};
use rocket_flex_session::Session;
#[derive(Clone)]
struct MySession {
user_id: String,
// ..other session fields
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for MySession {
type Error = &'r str; // or your custom error type
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
// Run the Session request guard (this guard should always succeed)
let session = req.guard::<Session<MySession>>().await.expect("should not fail");
// Get the `MySession` session data, or if it's `None`, send an Unauthorized error
match session.get() {
Some(my_session) => Outcome::Success(my_session),
None => Outcome::Error((Status::Unauthorized, "Not logged in")),
}
}
}
// Use our new `MySession` request guard in a route handler
#[rocket::get("/user")]
fn get_user(session: MySession) -> String {
return format!("Logged in as user {}!", session.user_id);
}
For more info and examples of this powerful pattern, please see Rocket’s documentation on request guards.
§HashMap session data
Instead of a custom struct, you can use a HashMap as your Session data type. This is particularly useful if you expect your session data structure to be inconsistent and/or change frequently. When using a HashMap, there are some additional helper functions to read and set keys.
use rocket_flex_session::Session;
use std::collections::HashMap;
type MySessionData = HashMap<String, String>;
#[rocket::post("/login")]
fn login(mut session: Session<MySessionData>) {
let user_id: Option<String> = session.get_key("user_id");
session.set_key("name".to_owned(), "Bob".to_owned());
}
§Feature flags
These features can be enabled as shown in Cargo’s documentation.
Name | Description |
---|---|
cookie | A cookie-based session store. Data is serialized using serde_json and then encrypted into the value of a cookie. |
redis_fred | A session store for Redis (and Redis-compatible databases), using the fred.rs crate. |
sqlx_postgres | A session store using PostgreSQL via the sqlx crate. |
rocket_okapi | Enables support for the rocket_okapi crate if needed. |
Modules§
- storage
- Storage implementations for sessions
Structs§
- Rocket
Flex Session - A Rocket fairing that enables sessions.
- Rocket
Flex Session Builder - Builder to configure the RocketFlexSession fairing
- Session
- Represents the current session state. When used as a request guard, it will
attempt to retrieve the session. The request guard will always succeed - if a
valid session wasn’t found,
session.get()
will returnNone
indicating an inactive session. - Session
Options - Options for configuring the session.