Sesión
Middleware que proporciona soporte para Sesión
.
¿Qué es una Sesión?
Una sesión es un conjunto de datos de usuario almacenados en el servidor, generalmente utilizados para rastrear el estado del usuario y guardar datos temporales. En aplicaciones web, las sesiones resuelven el problema de que el protocolo HTTP no mantenga estado, permitiendo al servidor reconocer múltiples solicitudes de un mismo usuario.
Uso de Sesión en Salvo
En Salvo, el middleware de Sesión proporciona una API sencilla para leer y escribir datos de sesión. A través de SessionDepot
se puede obtener una instancia de sesión, y con métodos como get
, set
, remove
, etc., se pueden gestionar los datos de sesión.
Usos comunes
- Autenticación de usuarios y gestión de estado de inicio de sesión
- Almacenamiento temporal de datos de formularios
- Guardado de preferencias de usuario
Código de ejemplo
session-login/src/main.rs
use salvo::prelude::*;
use salvo::session::{CookieStore, Session, SessionDepotExt, SessionHandler};
#[tokio::main]
async fn main() {
tracing_subscriber::fmt().init();
let session_handler = SessionHandler::builder(
CookieStore::new(),
b"secretabsecretabsecretabsecretabsecretabsecretabsecretabsecretab",
)
.build()
.unwrap();
let router = Router::new()
.hoop(session_handler)
.get(home)
.push(Router::with_path("login").get(login).post(login))
.push(Router::with_path("logout").get(logout));
let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
Server::new(acceptor).serve(router).await;
}
#[handler]
pub async fn login(req: &mut Request, depot: &mut Depot, res: &mut Response) {
if req.method() == salvo::http::Method::POST {
let mut session = Session::new();
session
.insert("username", req.form::<String>("username").await.unwrap())
.unwrap();
depot.set_session(session);
res.render(Redirect::other("/"));
} else {
res.render(Text::Html(LOGIN_HTML));
}
}
#[handler]
pub async fn logout(depot: &mut Depot, res: &mut Response) {
if let Some(session) = depot.session_mut() {
session.remove("username");
}
res.render(Redirect::other("/"));
}
#[handler]
pub async fn home(depot: &mut Depot, res: &mut Response) {
let mut content = r#"<a href="login">Login</h1>"#.into();
if let Some(session) = depot.session_mut() {
if let Some(username) = session.get::<String>("username") {
content = format!(r#"Hello, {username}. <br><a href="logout">Logout</h1>"#);
}
}
res.render(Text::Html(content));
}
static LOGIN_HTML: &str = r#"<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="/login" method="post">
<h1>Login</h1>
<input type="text" name="username" />
<button type="submit" id="submit">Submit</button>
</form>
</body>
</html>
"#;