Skip to main content

sa_token_core/
token_session.rs

1// Author: 金书记
2//
3//! Token-Session 双轨(独立于 Account-Session)
4
5use crate::error::{SaTokenError, SaTokenResult};
6use crate::manager::SaTokenManager;
7use crate::session::SaSession;
8use crate::token::TokenValue;
9
10impl SaTokenManager {
11    fn token_session_key(&self, token: &str) -> String {
12        self.config.make_key("token-session:", token)
13    }
14
15    /// 获取 Token-Session(不存在时按配置创建)
16    pub async fn get_token_session(&self, token: &TokenValue) -> SaTokenResult<SaSession> {
17        if self.config.token_session_check_login && !self.is_valid(token).await {
18            return Err(SaTokenError::NotLogin);
19        }
20
21        let key = self.token_session_key(token.as_str());
22        if let Some(value) = self
23            .storage
24            .get(&key)
25            .await
26            .map_err(|e| SaTokenError::StorageError(e.to_string()))?
27        {
28            let session: SaSession = serde_json::from_str(&value)?;
29            return Ok(session);
30        }
31
32        if self.config.right_now_create_token_session {
33            let session = SaSession::new(format!("token-session:{}", token.as_str()));
34            self.save_token_session(token, &session).await?;
35            Ok(session)
36        } else {
37            Ok(SaSession::new(format!("token-session:{}", token.as_str())))
38        }
39    }
40
41    /// 匿名 Token-Session(不校验登录)
42    pub async fn get_anon_token_session(&self, token: &TokenValue) -> SaTokenResult<SaSession> {
43        let key = self.token_session_key(token.as_str());
44        if let Some(value) = self
45            .storage
46            .get(&key)
47            .await
48            .map_err(|e| SaTokenError::StorageError(e.to_string()))?
49        {
50            return Ok(serde_json::from_str(&value)?);
51        }
52        Ok(SaSession::new(format!("token-session:{}", token.as_str())))
53    }
54
55    pub async fn save_token_session(
56        &self,
57        token: &TokenValue,
58        session: &SaSession,
59    ) -> SaTokenResult<()> {
60        let key = self.token_session_key(token.as_str());
61        let value = serde_json::to_string(session)?;
62        let ttl = self.config.timeout_duration();
63        self.storage
64            .set(&key, &value, ttl)
65            .await
66            .map_err(|e| SaTokenError::StorageError(e.to_string()))
67    }
68
69    pub async fn delete_token_session(&self, token: &TokenValue) -> SaTokenResult<()> {
70        self.storage
71            .delete(&self.token_session_key(token.as_str()))
72            .await
73            .map_err(|e| SaTokenError::StorageError(e.to_string()))
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80    use crate::config::SaTokenConfig;
81    use sa_token_storage_memory::MemoryStorage;
82    use std::sync::Arc;
83
84    #[tokio::test]
85    async fn token_session_independent_from_account_session() {
86        let config = SaTokenConfig::builder()
87            .right_now_create_token_session(true)
88            .build_config();
89        let mgr = SaTokenManager::new(Arc::new(MemoryStorage::new()), config);
90        let token = mgr.login("u1").await.unwrap();
91        let ts = mgr.get_token_session(&token).await.unwrap();
92        let mut ts = ts;
93        ts.set("k", "v").unwrap();
94        mgr.save_token_session(&token, &ts).await.unwrap();
95
96        let account = mgr.get_session("u1").await.unwrap();
97        assert!(account.get::<String>("k").is_none());
98
99        let loaded = mgr.get_token_session(&token).await.unwrap();
100        assert_eq!(loaded.get::<String>("k"), Some("v".to_string()));
101    }
102}