salvo_csrf/
session_store.rs

1use salvo_core::{Depot, Error, Request, Response};
2use salvo_session::SessionDepotExt;
3
4use super::{CsrfCipher, CsrfStore};
5
6/// A `CsrfStore` implementation that stores the CSRF proof in a session.
7#[derive(Debug)]
8pub struct SessionStore {
9    name: String,
10}
11impl Default for SessionStore {
12    fn default() -> Self {
13        Self::new()
14    }
15}
16
17impl SessionStore {
18    /// Create a new `SessionStore`.
19    pub fn new() -> Self {
20        Self {
21            name: "salvo.csrf".into(),
22        }
23    }
24}
25
26impl CsrfStore for SessionStore {
27    type Error = Error;
28    async fn load<C: CsrfCipher>(&self, _req: &mut Request, depot: &mut Depot, _cipher: &C) -> Option<(String, String)> {
29        depot
30            .session()
31            .and_then(|s| s.get::<String>(&self.name))
32            .and_then(|s| s.split_once('.').map(|(t, p)| (t.into(), p.into())))
33    }
34    async fn save(
35        &self,
36        _req: &mut Request,
37        depot: &mut Depot,
38        _res: &mut Response,
39        token: &str,
40        proof: &str,
41    ) -> Result<(), Self::Error> {
42        depot
43            .session_mut()
44            .expect("session must be exist")
45            .insert(&self.name, format!("{token}.{proof}"))?;
46        Ok(())
47    }
48}