Sitzung

Middleware, das Unterstützung für Session bietet.

Was ist eine Sitzung

Eine Sitzung bezieht sich auf Benutzerdaten, die auf der Serverseite gespeichert werden, typischerweise verwendet, um den Benutzerstatus zu verfolgen und temporäre Daten zu speichern. In Webanwendungen adressiert die Sitzung die zustandslose Natur des HTTP-Protokolls, wodurch der Server mehrere Anfragen desselben Benutzers erkennen kann.

Verwendung von Sitzungen in Salvo

In Salvo bietet die Session-Middleware eine einfache API zum Lesen und Schreiben von Sitzungsdaten. Das SessionDepot kann verwendet werden, um eine Sitzungsinstanz zu erhalten, während Methoden wie get, set und remove die Verwaltung von Sitzungsdaten ermöglichen.

Häufige Anwendungsfälle

  • Benutzerauthentifizierung und Verwaltung des Anmeldestatus
  • Temporäre Speicherung von Formulardaten
  • Speicherung von Benutzereinstellungen

Beispielcode

main.rs
Cargo.toml
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:8698").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()
        && 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>
"#;