Сессия
Промежуточное ПО, обеспечивающее поддержку Session
.
Что такое Session
Session — это данные пользователя, хранящиеся на стороне сервера, обычно используемые для отслеживания состояния пользователя и сохранения временных данных. В веб-приложениях Session решает проблему отсутствия состояния в протоколе HTTP, позволяя серверу идентифицировать множественные запросы от одного пользователя.
Использование Session в Salvo
В Salvo промежуточное ПО Session предоставляет простой API для чтения и записи данных сессии. Через SessionDepot
можно получить экземпляр сессии, а с помощью методов get
, set
, remove
и других можно управлять данными сессии.
Распространённые сценарии использования
- Аутентификация пользователя и управление статусом входа
- Временное хранение данных форм
- Сохранение пользовательских настроек
Пример кода
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>
"#;