sa_token_core/
distributed.rs

1//! Distributed Session Management Module | 分布式 Session 管理模块
2//!
3//! # Overview | 概述
4//!
5//! This module enables **distributed session management** for microservices architecture,
6//! allowing multiple services to share authentication sessions seamlessly.
7//! 本模块为微服务架构提供**分布式 Session 管理**,允许多个服务无缝共享认证会话。
8//!
9//! ## Architecture Context | 架构上下文
10//!
11//! ```text
12//! ┌────────────────────────────────────────────────────────────────────┐
13//! │                   Microservices Architecture                       │
14//! │                   微服务架构                                        │
15//! └────────────────────────────────────────────────────────────────────┘
16//!
17//!    ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
18//!    │  Service A   │  │  Service B   │  │  Service C   │
19//!    │  (User API)  │  │  (Order API) │  │  (Pay API)   │
20//!    └──────┬───────┘  └──────┬───────┘  └──────┬───────┘
21//!           │                  │                  │
22//!           └──────────────────┼──────────────────┘
23//!                              │
24//!                    ┌─────────▼──────────┐
25//!                    │  Distributed       │
26//!                    │  Session Storage   │
27//!                    │  (Redis/Database)  │
28//!                    └────────────────────┘
29//!
30//! Each service can:
31//! 每个服务可以:
32//!   1. Create sessions for users
33//!      为用户创建会话
34//!   2. Access sessions created by other services
35//!      访问其他服务创建的会话
36//!   3. Share user authentication state
37//!      共享用户认证状态
38//! ```
39//!
40//! ## Key Use Cases | 关键使用场景
41//!
42//! ### 1. Single Sign-On (SSO) Across Services | 跨服务单点登录
43//!
44//! ```text
45//! Scenario: User logs in to Service A and accesses Service B
46//! 场景:用户登录服务 A 并访问服务 B
47//!
48//! 1. User → Service A: Login
49//!    用户 → 服务 A:登录
50//!    ├─ Service A creates session: session_id = "abc123"
51//!    │  服务 A 创建会话:session_id = "abc123"
52//!    └─ Saves to distributed storage
53//!       保存到分布式存储
54//!
55//! 2. User → Service B: Request with session_id = "abc123"
56//!    用户 → 服务 B:请求带 session_id = "abc123"
57//!    ├─ Service B retrieves session from storage
58//!    │  服务 B 从存储中获取会话
59//!    ├─ Validates user is authenticated
60//!    │  验证用户已认证
61//!    └─ Processes request ✅
62//!       处理请求 ✅
63//!
64//! No need to log in again! 无需再次登录!
65//! ```
66//!
67//! ### 2. Session Sharing for User Context | 会话共享用户上下文
68//!
69//! ```text
70//! Service A stores: { "user_role": "admin", "department": "IT" }
71//! 服务 A 存储:{ "user_role": "admin", "department": "IT" }
72//!
73//! Service B reads: Same session attributes available
74//! 服务 B 读取:相同的会话属性可用
75//!
76//! Service C updates: { "last_order": "order_123" }
77//! 服务 C 更新:{ "last_order": "order_123" }
78//!
79//! All services share the same session state!
80//! 所有服务共享相同的会话状态!
81//! ```
82//!
83//! ### 3. Multi-Device Session Management | 多设备会话管理
84//!
85//! ```text
86//! User: user_123
87//!   ├─ Session 1: Web (Service A)
88//!   │  会话 1:网页(服务 A)
89//!   ├─ Session 2: Mobile (Service B)
90//!   │  会话 2:移动端(服务 B)
91//!   └─ Session 3: Desktop (Service C)
92//!      会话 3:桌面端(服务 C)
93//!
94//! All sessions can be:
95//! 所有会话可以:
96//!   - Listed: get_sessions_by_login_id()
97//!   - Managed individually
98//!   - Terminated all at once: delete_all_sessions()
99//! ```
100//!
101//! ## Integration with Sa-Token | 与 Sa-Token 的集成
102//!
103//! ```text
104//! ┌─────────────────────────────────────────────────────────┐
105//! │               Sa-Token Core Flow                        │
106//! │               Sa-Token 核心流程                          │
107//! └─────────────────────────────────────────────────────────┘
108//!
109//! SaTokenManager::login()
110//!   ├─ 1. Generate token
111//!   │     生成 token
112//!   ├─ 2. Create TokenInfo
113//!   │     创建 TokenInfo
114//!   └─ 3. Create DistributedSession (if enabled)
115//!          创建 DistributedSession(如果启用)
116//!          ├─ session_id: UUID
117//!          ├─ login_id: user's login ID
118//!          ├─ token: access token
119//!          ├─ service_id: current service
120//!          └─ attributes: custom data
121//!
122//! StpUtil::get_session()
123//!   └─ Retrieves distributed session
124//!      获取分布式会话
125//!
126//! StpUtil::logout()
127//!   └─ Deletes distributed session(s)
128//!      删除分布式会话
129//! ```
130
131//!
132//! ## Workflow Diagrams | 工作流程图
133//!
134//! ### Complete Session Lifecycle | 完整会话生命周期
135//!
136//! ```text
137//! ┌──────────────────────────────────────────────────────────────────┐
138//! │                    Session Lifecycle                             │
139//! │                    会话生命周期                                   │
140//! └──────────────────────────────────────────────────────────────────┘
141//!
142//! User                Service A           Storage           Service B
143//! 用户                服务 A              存储              服务 B
144//!  │                     │                   │                   │
145//!  │  1. Login           │                   │                   │
146//!  │  登录               │                   │                   │
147//!  ├────────────────────▶│                   │                   │
148//!  │                     │  2. create_session()                  │
149//!  │                     │  创建会话          │                   │
150//!  │                     │  ├─ session_id: uuid                  │
151//!  │                     │  ├─ login_id: user_123                │
152//!  │                     │  ├─ token: access_token               │
153//!  │                     │  └─ service_id: service-a             │
154//!  │                     │                   │                   │
155//!  │                     │  3. save_session()│                   │
156//!  │                     │  保存会话          │                   │
157//!  │                     ├──────────────────▶│                   │
158//!  │                     │                   │  Store with TTL   │
159//!  │                     │                   │  存储并设置 TTL    │
160//!  │                     │                   │                   │
161//!  │  4. session_id      │                   │                   │
162//!  │  返回会话 ID        │                   │                   │
163//!  │◀────────────────────│                   │                   │
164//!  │                     │                   │                   │
165//!  │  5. Request to Service B with session_id                    │
166//!  │  带 session_id 请求服务 B                                    │
167//!  ├────────────────────────────────────────────────────────────▶│
168//!  │                     │                   │                   │
169//!  │                     │                   │  6. get_session() │
170//!  │                     │                   │  获取会话          │
171//!  │                     │                   │◀──────────────────│
172//!  │                     │                   │                   │
173//!  │                     │                   │  7. Return session│
174//!  │                     │                   │  返回会话数据      │
175//!  │                     │                   ├──────────────────▶│
176//!  │                     │                   │                   │
177//!  │                     │                   │  8. refresh_session()
178//!  │                     │                   │  刷新会话          │
179//!  │                     │                   │  (update last_access)
180//!  │                     │                   │◀──────────────────│
181//!  │                     │                   │                   │
182//!  │  9. Response        │                   │                   │
183//!  │  响应               │                   │                   │
184//!  │◀────────────────────────────────────────────────────────────│
185//!  │                     │                   │                   │
186//!  │  10. Logout         │                   │                   │
187//!  │  登出               │                   │                   │
188//!  ├────────────────────▶│                   │                   │
189//!  │                     │  11. delete_session()                 │
190//!  │                     │  删除会话          │                   │
191//!  │                     ├──────────────────▶│                   │
192//!  │                     │                   │  Remove from storage
193//!  │                     │                   │  从存储中移除      │
194//!  │                     │                   │                   │
195//!  │  12. Logout Success │                   │                   │
196//!  │  登出成功           │                   │                   │
197//!  │◀────────────────────│                   │                   │
198//!  │                     │                   │                   │
199//! ```
200//!
201//! ### Service Authentication Flow | 服务认证流程
202//!
203//! ```text
204//! ┌──────────────────────────────────────────────────────────────────┐
205//! │                Service Inter-Communication                       │
206//! │                服务间通信                                         │
207//! └──────────────────────────────────────────────────────────────────┘
208//!
209//! Service B          Service A (Session Manager)          Storage
210//! 服务 B             服务 A(会话管理器)                  存储
211//!   │                        │                               │
212//!   │  1. Register           │                               │
213//!   │  注册服务              │                               │
214//!   │  ├─ service_id         │                               │
215//!   │  ├─ service_name       │                               │
216//!   │  ├─ secret_key         │                               │
217//!   │  └─ permissions        │                               │
218//!   ├───────────────────────▶│                               │
219//!   │                        │  Store credentials            │
220//!   │                        │  存储凭证                      │
221//!   │                        │  (in memory)                  │
222//!   │                        │                               │
223//!   │  2. Registered ✅      │                               │
224//!   │◀───────────────────────│                               │
225//!   │                        │                               │
226//!   │  3. Access session     │                               │
227//!   │  访问会话              │                               │
228//!   │  ├─ service_id         │                               │
229//!   │  ├─ secret_key         │                               │
230//!   │  └─ session_id         │                               │
231//!   ├───────────────────────▶│                               │
232//!   │                        │  4. verify_service()          │
233//!   │                        │  验证服务                      │
234//!   │                        │  ├─ Lookup service            │
235//!   │                        │  └─ Compare secret_key        │
236//!   │                        │                               │
237//!   │                        │  5. get_session()             │
238//!   │                        │  获取会话                      │
239//!   │                        ├──────────────────────────────▶│
240//!   │                        │                               │
241//!   │                        │  6. Return session            │
242//!   │                        │  返回会话                      │
243//!   │                        │◀──────────────────────────────│
244//!   │                        │                               │
245//!   │  7. Session data ✅    │                               │
246//!   │◀───────────────────────│                               │
247//!   │                        │                               │
248//! ```
249//!
250//! ## Storage Backends | 存储后端
251//!
252//! The module is storage-agnostic. You can implement custom backends:
253//! 本模块与存储无关。您可以实现自定义后端:
254//!
255//! ### Redis Implementation (Recommended) | Redis 实现(推荐)
256//!
257//! ```rust,ignore
258//! use redis::AsyncCommands;
259//!
260//! pub struct RedisDistributedStorage {
261//!     client: redis::Client,
262//! }
263//!
264//! #[async_trait]
265//! impl DistributedSessionStorage for RedisDistributedStorage {
266//!     async fn save_session(&self, session: DistributedSession, ttl: Option<Duration>) 
267//!         -> Result<(), SaTokenError> 
268//!     {
269//!         let mut conn = self.client.get_async_connection().await?;
270//!         let key = format!("distributed:session:{}", session.session_id);
271//!         let value = serde_json::to_string(&session)?;
272//!         
273//!         if let Some(ttl) = ttl {
274//!             conn.set_ex(&key, value, ttl.as_secs() as usize).await?;
275//!         } else {
276//!             conn.set(&key, value).await?;
277//!         }
278//!         
279//!         // Index by login_id
280//!         let index_key = format!("distributed:login:{}", session.login_id);
281//!         conn.sadd(index_key, &session.session_id).await?;
282//!         
283//!         Ok(())
284//!     }
285//!     
286//!     // ... other methods
287//! }
288//! ```
289//!
290//! ### Database Implementation | 数据库实现
291//!
292//! ```rust,ignore
293//! use sqlx::PgPool;
294//!
295//! pub struct PostgresDistributedStorage {
296//!     pool: PgPool,
297//! }
298//!
299//! #[async_trait]
300//! impl DistributedSessionStorage for PostgresDistributedStorage {
301//!     async fn save_session(&self, session: DistributedSession, ttl: Option<Duration>) 
302//!         -> Result<(), SaTokenError> 
303//!     {
304//!         let expires_at = ttl.map(|t| Utc::now() + chrono::Duration::from_std(t).unwrap());
305//!         
306//!         sqlx::query!(
307//!             "INSERT INTO distributed_sessions 
308//!              (session_id, login_id, token, service_id, attributes, expires_at)
309//!              VALUES ($1, $2, $3, $4, $5, $6)
310//!              ON CONFLICT (session_id) DO UPDATE 
311//!              SET attributes = $5, last_access = NOW()",
312//!             session.session_id,
313//!             session.login_id,
314//!             session.token,
315//!             session.service_id,
316//!             serde_json::to_value(&session.attributes)?,
317//!             expires_at,
318//!         )
319//!         .execute(&self.pool)
320//!         .await?;
321//!         
322//!         Ok(())
323//!     }
324//!     
325//!     // ... other methods
326//! }
327//! ```
328//!
329//! ## Best Practices | 最佳实践
330//!
331//! ### 1. Service Registration | 服务注册
332//!
333//! ```rust,ignore
334//! // Initialize each service with unique credentials
335//! // 为每个服务初始化唯一凭证
336//! let credential = ServiceCredential {
337//!     service_id: "user-service".to_string(),
338//!     service_name: "User Management Service".to_string(),
339//!     secret_key: generate_secure_secret(), // Use crypto-secure generation
340//!     created_at: Utc::now(),
341//!     permissions: vec!["user.read".to_string(), "user.write".to_string()],
342//! };
343//! manager.register_service(credential).await;
344//! ```
345//!
346//! ### 2. Session Creation with Context | 带上下文的会话创建
347//!
348//! ```rust,ignore
349//! // Create session with user context
350//! // 创建带用户上下文的会话
351//! let session = manager.create_session(login_id, token).await?;
352//!
353//! // Add relevant attributes immediately
354//! // 立即添加相关属性
355//! manager.set_attribute(&session.session_id, "user_role".to_string(), "admin".to_string()).await?;
356//! manager.set_attribute(&session.session_id, "department".to_string(), "IT".to_string()).await?;
357//! manager.set_attribute(&session.session_id, "login_device".to_string(), "web".to_string()).await?;
358//! ```
359//!
360//! ### 3. Cross-Service Access Pattern | 跨服务访问模式
361//!
362//! ```rust,ignore
363//! // Service B accesses session created by Service A
364//! // 服务 B 访问服务 A 创建的会话
365//! 
366//! // 1. Verify service identity
367//! // 验证服务身份
368//! let service_cred = manager.verify_service("service-b", request.secret).await?;
369//!
370//! // 2. Check permissions
371//! // 检查权限
372//! if !service_cred.permissions.contains(&"session.read".to_string()) {
373//!     return Err(SaTokenError::PermissionDenied);
374//! }
375//!
376//! // 3. Access session
377//! // 访问会话
378//! let session = manager.get_session(&request.session_id).await?;
379//!
380//! // 4. Refresh to keep session alive
381//! // 刷新以保持会话活跃
382//! manager.refresh_session(&session.session_id).await?;
383//! ```
384//!
385//! ### 4. Multi-Device Logout | 多设备登出
386//!
387//! ```rust,ignore
388//! // Logout from all devices
389//! // 从所有设备登出
390//! manager.delete_all_sessions(&login_id).await?;
391//!
392//! // Or logout specific session
393//! // 或登出特定会话
394//! manager.delete_session(&session_id).await?;
395//! ```
396//!
397//! ### 5. Session Monitoring | 会话监控
398//!
399//! ```rust,ignore
400//! // Monitor user's active sessions
401//! // 监控用户的活跃会话
402//! let sessions = manager.get_sessions_by_login_id(&login_id).await?;
403//! 
404//! for session in sessions {
405//!     println!("Session: {} from service: {}, last active: {}", 
406//!         session.session_id,
407//!         session.service_id,
408//!         session.last_access
409//!     );
410//!     
411//!     // Check for suspicious activity
412//!     // 检查可疑活动
413//!     if is_suspicious(&session) {
414//!         manager.delete_session(&session.session_id).await?;
415//!     }
416//! }
417//! ```
418//!
419//! ## Security Considerations | 安全考虑
420//!
421//! ```text
422//! 1. ✅ Service Authentication | 服务认证
423//!    - Each service has unique secret_key
424//!    - Verify credentials before granting access
425//!    - Rotate keys periodically
426//!
427//! 2. ✅ Permission-Based Access | 基于权限的访问
428//!    - Services have explicit permissions
429//!    - Check permissions before operations
430//!    - Implement least-privilege principle
431//!
432//! 3. ✅ Session Timeout | 会话超时
433//!    - Configure appropriate TTL
434//!    - Auto-expire inactive sessions
435//!    - Refresh on active use
436//!
437//! 4. ✅ Data Encryption | 数据加密
438//!    - Encrypt sensitive session attributes
439//!    - Use TLS for inter-service communication
440//!    - Encrypt data at rest in storage
441//!
442//! 5. ✅ Audit Logging | 审计日志
443//!    - Log session creation/deletion
444//!    - Track cross-service access
445//!    - Monitor for anomalies
446//! ```
447
448use crate::error::SaTokenError;
449use async_trait::async_trait;
450use serde::{Deserialize, Serialize};
451use std::collections::HashMap;
452use std::sync::Arc;
453use std::time::Duration;
454use chrono::{DateTime, Utc};
455use tokio::sync::RwLock;
456
457/// Distributed session data structure
458/// 分布式 Session 数据结构
459///
460/// Represents a session that can be shared across multiple services
461/// 表示可以在多个服务之间共享的 Session
462#[derive(Debug, Clone, Serialize, Deserialize)]
463pub struct DistributedSession {
464    /// Unique session identifier | 唯一 Session 标识符
465    pub session_id: String,
466    
467    /// User login ID | 用户登录 ID
468    pub login_id: String,
469    
470    /// Authentication token | 认证 Token
471    pub token: String,
472    
473    /// ID of the service that created this session | 创建此 Session 的服务 ID
474    pub service_id: String,
475    
476    /// Session creation time | Session 创建时间
477    pub create_time: DateTime<Utc>,
478    
479    /// Last access time | 最后访问时间
480    pub last_access: DateTime<Utc>,
481    
482    /// Session attributes (key-value pairs) | Session 属性(键值对)
483    pub attributes: HashMap<String, String>,
484}
485
486/// Service credential for inter-service authentication
487/// 服务间认证的服务凭证
488///
489/// Contains service identification and permission information
490/// 包含服务标识和权限信息
491#[derive(Debug, Clone, Serialize, Deserialize)]
492pub struct ServiceCredential {
493    /// Unique service identifier | 唯一服务标识符
494    pub service_id: String,
495    
496    /// Human-readable service name | 可读的服务名称
497    pub service_name: String,
498    
499    /// Service authentication secret key | 服务认证密钥
500    pub secret_key: String,
501    
502    /// Service registration time | 服务注册时间
503    pub created_at: DateTime<Utc>,
504    
505    /// List of permissions this service has | 该服务拥有的权限列表
506    pub permissions: Vec<String>,
507}
508
509/// Distributed session storage trait
510/// 分布式 Session 存储 trait
511///
512/// Implement this trait to provide custom storage backends
513/// 实现此 trait 以提供自定义存储后端
514#[async_trait]
515pub trait DistributedSessionStorage: Send + Sync {
516    /// Save a session to storage with optional TTL
517    /// 保存 Session 到存储,可选 TTL
518    ///
519    /// # Arguments | 参数
520    /// * `session` - Session to save | 要保存的 Session
521    /// * `ttl` - Time-to-live duration | 生存时间
522    async fn save_session(&self, session: DistributedSession, ttl: Option<Duration>) -> Result<(), SaTokenError>;
523    
524    /// Get a session from storage
525    /// 从存储获取 Session
526    ///
527    /// # Arguments | 参数
528    /// * `session_id` - Session identifier | Session 标识符
529    async fn get_session(&self, session_id: &str) -> Result<Option<DistributedSession>, SaTokenError>;
530    
531    /// Delete a session from storage
532    /// 从存储删除 Session
533    ///
534    /// # Arguments | 参数
535    /// * `session_id` - Session identifier | Session 标识符
536    async fn delete_session(&self, session_id: &str) -> Result<(), SaTokenError>;
537    
538    /// Get all sessions for a specific user
539    /// 获取特定用户的所有 Sessions
540    ///
541    /// # Arguments | 参数
542    /// * `login_id` - User login ID | 用户登录 ID
543    async fn get_sessions_by_login_id(&self, login_id: &str) -> Result<Vec<DistributedSession>, SaTokenError>;
544}
545
546/// Distributed session manager
547/// 分布式 Session 管理器
548///
549/// Manages distributed sessions and service authentication
550/// 管理分布式 Sessions 和服务认证
551pub struct DistributedSessionManager {
552    /// Session storage backend | Session 存储后端
553    storage: Arc<dyn DistributedSessionStorage>,
554    
555    /// Current service ID | 当前服务 ID
556    service_id: String,
557    
558    /// Default session timeout | 默认 Session 超时时间
559    session_timeout: Duration,
560    
561    /// Registered service credentials | 已注册的服务凭证
562    service_credentials: Arc<RwLock<HashMap<String, ServiceCredential>>>,
563}
564
565impl DistributedSessionManager {
566    /// Create a new distributed session manager
567    /// 创建新的分布式 Session 管理器
568    ///
569    /// # Arguments | 参数
570    /// * `storage` - Session storage implementation | Session 存储实现
571    /// * `service_id` - ID of this service | 此服务的 ID
572    /// * `session_timeout` - Default session timeout | 默认 Session 超时时间
573    ///
574    /// # Example | 示例
575    /// ```rust,ignore
576    /// let storage = Arc::new(MyDistributedStorage::new());
577    /// let manager = DistributedSessionManager::new(
578    ///     storage,
579    ///     "my-service".to_string(),
580    ///     Duration::from_secs(3600),
581    /// );
582    /// ```
583    pub fn new(
584        storage: Arc<dyn DistributedSessionStorage>,
585        service_id: String,
586        session_timeout: Duration,
587    ) -> Self {
588        Self {
589            storage,
590            service_id,
591            session_timeout,
592            service_credentials: Arc::new(RwLock::new(HashMap::new())),
593        }
594    }
595
596    /// Register a service for inter-service authentication
597    /// 注册服务以进行服务间认证
598    ///
599    /// # Arguments | 参数
600    /// * `credential` - Service credential information | 服务凭证信息
601    ///
602    /// # Example | 示例
603    /// ```rust,ignore
604    /// let credential = ServiceCredential {
605    ///     service_id: "api-gateway".to_string(),
606    ///     service_name: "API Gateway".to_string(),
607    ///     secret_key: "secret123".to_string(),
608    ///     created_at: Utc::now(),
609    ///     permissions: vec!["read".to_string(), "write".to_string()],
610    /// };
611    /// manager.register_service(credential).await;
612    /// ```
613    pub async fn register_service(&self, credential: ServiceCredential) {
614        let mut credentials = self.service_credentials.write().await;
615        credentials.insert(credential.service_id.clone(), credential);
616    }
617
618    /// Verify a service's credentials
619    /// 验证服务的凭证
620    ///
621    /// # Arguments | 参数
622    /// * `service_id` - Service identifier | 服务标识符
623    /// * `secret` - Service secret key | 服务密钥
624    ///
625    /// # Returns | 返回值
626    /// * `Ok(ServiceCredential)` - Service authenticated | 服务已认证
627    /// * `Err(PermissionDenied)` - Invalid credentials | 凭证无效
628    ///
629    /// # Example | 示例
630    /// ```rust,ignore
631    /// match manager.verify_service("api-gateway", "secret123").await {
632    ///     Ok(cred) => println!("Service {} verified", cred.service_name),
633    ///     Err(e) => println!("Verification failed: {}", e),
634    /// }
635    /// ```
636    pub async fn verify_service(&self, service_id: &str, secret: &str) -> Result<ServiceCredential, SaTokenError> {
637        let credentials = self.service_credentials.read().await;
638        if let Some(cred) = credentials.get(service_id) {
639            if cred.secret_key == secret {
640                return Ok(cred.clone());
641            }
642        }
643        Err(SaTokenError::PermissionDenied)
644    }
645
646    /// Create a new distributed session
647    /// 创建新的分布式 Session
648    ///
649    /// # Arguments | 参数
650    /// * `login_id` - User login ID | 用户登录 ID
651    /// * `token` - Authentication token | 认证 Token
652    ///
653    /// # Returns | 返回值
654    /// * `Ok(DistributedSession)` - Session created | Session 已创建
655    /// * `Err(SaTokenError)` - Creation failed | 创建失败
656    ///
657    /// # Example | 示例
658    /// ```rust,ignore
659    /// let session = manager.create_session(
660    ///     "user123".to_string(),
661    ///     "token456".to_string(),
662    /// ).await?;
663    /// println!("Session created: {}", session.session_id);
664    /// ```
665    pub async fn create_session(
666        &self,
667        login_id: String,
668        token: String,
669    ) -> Result<DistributedSession, SaTokenError> {
670        let session = DistributedSession {
671            session_id: uuid::Uuid::new_v4().to_string(),
672            login_id,
673            token,
674            service_id: self.service_id.clone(),
675            create_time: Utc::now(),
676            last_access: Utc::now(),
677            attributes: HashMap::new(),
678        };
679
680        self.storage.save_session(session.clone(), Some(self.session_timeout)).await?;
681        Ok(session)
682    }
683
684    /// Get a session by ID
685    /// 通过 ID 获取 Session
686    ///
687    /// # Arguments | 参数
688    /// * `session_id` - Session identifier | Session 标识符
689    ///
690    /// # Returns | 返回值
691    /// * `Ok(DistributedSession)` - Session found | 找到 Session
692    /// * `Err(SessionNotFound)` - Session not found | 未找到 Session
693    ///
694    /// # Example | 示例
695    /// ```rust,ignore
696    /// let session = manager.get_session("session-id-123").await?;
697    /// println!("User: {}", session.login_id);
698    /// ```
699    pub async fn get_session(&self, session_id: &str) -> Result<DistributedSession, SaTokenError> {
700        self.storage.get_session(session_id).await?
701            .ok_or(SaTokenError::SessionNotFound)
702    }
703
704    /// Update an existing session
705    /// 更新现有 Session
706    ///
707    /// # Arguments | 参数
708    /// * `session` - Updated session data | 更新后的 Session 数据
709    ///
710    /// # Example | 示例
711    /// ```rust,ignore
712    /// let mut session = manager.get_session("session-id").await?;
713    /// session.attributes.insert("role".to_string(), "admin".to_string());
714    /// manager.update_session(session).await?;
715    /// ```
716    pub async fn update_session(&self, session: DistributedSession) -> Result<(), SaTokenError> {
717        self.storage.save_session(session, Some(self.session_timeout)).await
718    }
719
720    /// Delete a session
721    /// 删除 Session
722    ///
723    /// # Arguments | 参数
724    /// * `session_id` - Session identifier | Session 标识符
725    ///
726    /// # Example | 示例
727    /// ```rust,ignore
728    /// manager.delete_session("session-id-123").await?;
729    /// ```
730    pub async fn delete_session(&self, session_id: &str) -> Result<(), SaTokenError> {
731        self.storage.delete_session(session_id).await
732    }
733
734    /// Refresh a session (update last access time)
735    /// 刷新 Session(更新最后访问时间)
736    ///
737    /// # Arguments | 参数
738    /// * `session_id` - Session identifier | Session 标识符
739    ///
740    /// # Example | 示例
741    /// ```rust,ignore
742    /// manager.refresh_session("session-id-123").await?;
743    /// ```
744    pub async fn refresh_session(&self, session_id: &str) -> Result<(), SaTokenError> {
745        let mut session = self.get_session(session_id).await?;
746        session.last_access = Utc::now();
747        self.update_session(session).await
748    }
749
750    /// Set a session attribute
751    /// 设置 Session 属性
752    ///
753    /// # Arguments | 参数
754    /// * `session_id` - Session identifier | Session 标识符
755    /// * `key` - Attribute key | 属性键
756    /// * `value` - Attribute value | 属性值
757    ///
758    /// # Example | 示例
759    /// ```rust,ignore
760    /// manager.set_attribute("session-id", "theme".to_string(), "dark".to_string()).await?;
761    /// ```
762    pub async fn set_attribute(
763        &self,
764        session_id: &str,
765        key: String,
766        value: String,
767    ) -> Result<(), SaTokenError> {
768        let mut session = self.get_session(session_id).await?;
769        session.attributes.insert(key, value);
770        session.last_access = Utc::now();
771        self.update_session(session).await
772    }
773
774    /// Get a session attribute
775    /// 获取 Session 属性
776    ///
777    /// # Arguments | 参数
778    /// * `session_id` - Session identifier | Session 标识符
779    /// * `key` - Attribute key | 属性键
780    ///
781    /// # Returns | 返回值
782    /// * `Some(value)` - Attribute found | 找到属性
783    /// * `None` - Attribute not found | 未找到属性
784    ///
785    /// # Example | 示例
786    /// ```rust,ignore
787    /// if let Some(theme) = manager.get_attribute("session-id", "theme").await? {
788    ///     println!("Theme: {}", theme);
789    /// }
790    /// ```
791    pub async fn get_attribute(
792        &self,
793        session_id: &str,
794        key: &str,
795    ) -> Result<Option<String>, SaTokenError> {
796        let session = self.get_session(session_id).await?;
797        Ok(session.attributes.get(key).cloned())
798    }
799
800    /// Remove a session attribute
801    /// 移除 Session 属性
802    ///
803    /// # Arguments | 参数
804    /// * `session_id` - Session identifier | Session 标识符
805    /// * `key` - Attribute key | 属性键
806    ///
807    /// # Example | 示例
808    /// ```rust,ignore
809    /// manager.remove_attribute("session-id", "temp_data").await?;
810    /// ```
811    pub async fn remove_attribute(
812        &self,
813        session_id: &str,
814        key: &str,
815    ) -> Result<(), SaTokenError> {
816        let mut session = self.get_session(session_id).await?;
817        session.attributes.remove(key);
818        session.last_access = Utc::now();
819        self.update_session(session).await
820    }
821
822    /// Get all sessions for a specific user
823    /// 获取特定用户的所有 Sessions
824    ///
825    /// # Arguments | 参数
826    /// * `login_id` - User login ID | 用户登录 ID
827    ///
828    /// # Returns | 返回值
829    /// Vector of sessions | Sessions 向量
830    ///
831    /// # Example | 示例
832    /// ```rust,ignore
833    /// let sessions = manager.get_sessions_by_login_id("user123").await?;
834    /// println!("User has {} active sessions", sessions.len());
835    /// ```
836    pub async fn get_sessions_by_login_id(&self, login_id: &str) -> Result<Vec<DistributedSession>, SaTokenError> {
837        self.storage.get_sessions_by_login_id(login_id).await
838    }
839
840    /// Delete all sessions for a specific user
841    /// 删除特定用户的所有 Sessions
842    ///
843    /// # Arguments | 参数
844    /// * `login_id` - User login ID | 用户登录 ID
845    ///
846    /// # Example | 示例
847    /// ```rust,ignore
848    /// manager.delete_all_sessions("user123").await?;
849    /// ```
850    pub async fn delete_all_sessions(&self, login_id: &str) -> Result<(), SaTokenError> {
851        let sessions = self.get_sessions_by_login_id(login_id).await?;
852        for session in sessions {
853            self.delete_session(&session.session_id).await?;
854        }
855        Ok(())
856    }
857}
858
859/// In-memory distributed session storage implementation
860/// 内存分布式 Session 存储实现
861///
862/// For testing and development purposes
863/// 用于测试和开发目的
864pub struct InMemoryDistributedStorage {
865    /// Sessions storage: session_id -> DistributedSession
866    /// Sessions 存储: session_id -> DistributedSession
867    sessions: Arc<RwLock<HashMap<String, DistributedSession>>>,
868    
869    /// Login index: login_id -> Vec<session_id>
870    /// 登录索引: login_id -> Vec<session_id>
871    login_index: Arc<RwLock<HashMap<String, Vec<String>>>>,
872}
873
874impl InMemoryDistributedStorage {
875    /// Create a new in-memory storage
876    /// 创建新的内存存储
877    pub fn new() -> Self {
878        Self {
879            sessions: Arc::new(RwLock::new(HashMap::new())),
880            login_index: Arc::new(RwLock::new(HashMap::new())),
881        }
882    }
883}
884
885impl Default for InMemoryDistributedStorage {
886    fn default() -> Self {
887        Self::new()
888    }
889}
890
891#[async_trait]
892impl DistributedSessionStorage for InMemoryDistributedStorage {
893    /// Save session to memory storage | 保存会话到内存存储
894    ///
895    /// # Implementation Details | 实现细节
896    ///
897    /// 1. Stores session in main HashMap by session_id
898    ///    在主 HashMap 中按 session_id 存储会话
899    /// 2. Updates login_index for quick user lookup
900    ///    更新 login_index 以快速查找用户
901    ///
902    /// # Note | 注意
903    ///
904    /// TTL is ignored in memory storage (for simplicity).
905    /// In production, use Redis or similar with built-in TTL support.
906    /// 内存存储中忽略 TTL(为简化实现)。
907    /// 在生产环境中,使用 Redis 或类似的内置 TTL 支持的存储。
908    async fn save_session(&self, session: DistributedSession, _ttl: Option<Duration>) -> Result<(), SaTokenError> {
909        let session_id = session.session_id.clone();
910        let login_id = session.login_id.clone();
911        
912        // 1. Store session in main map
913        // 在主映射中存储会话
914        let mut sessions = self.sessions.write().await;
915        sessions.insert(session_id.clone(), session);
916        
917        // 2. Update login index for this user
918        // 更新此用户的登录索引
919        let mut index = self.login_index.write().await;
920        let session_list = index.entry(login_id).or_insert_with(Vec::new);
921        
922        // Add only if not already present (prevent duplicates)
923        // 仅在不存在时添加(防止重复)
924        if !session_list.contains(&session_id) {
925            session_list.push(session_id);
926        }
927        
928        Ok(())
929    }
930
931    /// Get session from memory storage | 从内存存储获取会话
932    ///
933    /// # Returns | 返回
934    ///
935    /// * `Ok(Some(session))` - Session found | 找到会话
936    /// * `Ok(None)` - Session not found | 未找到会话
937    async fn get_session(&self, session_id: &str) -> Result<Option<DistributedSession>, SaTokenError> {
938        let sessions = self.sessions.read().await;
939        Ok(sessions.get(session_id).cloned())
940    }
941
942    /// Delete session from memory storage | 从内存存储删除会话
943    ///
944    /// # Implementation Details | 实现细节
945    ///
946    /// 1. Removes session from main HashMap
947    ///    从主 HashMap 中移除会话
948    /// 2. Removes session_id from login_index
949    ///    从 login_index 中移除 session_id
950    /// 3. Cleans up empty index entries
951    ///    清理空的索引条目
952    async fn delete_session(&self, session_id: &str) -> Result<(), SaTokenError> {
953        // 1. Remove from main storage and get session data
954        // 从主存储中移除并获取会话数据
955        let mut sessions = self.sessions.write().await;
956        if let Some(session) = sessions.remove(session_id) {
957            // 2. Update login index
958            // 更新登录索引
959            let mut index = self.login_index.write().await;
960            if let Some(session_ids) = index.get_mut(&session.login_id) {
961                // Remove this session_id from the list
962                // 从列表中移除此 session_id
963                session_ids.retain(|id| id != session_id);
964                
965                // 3. Clean up: remove login_id entry if no sessions left
966                // 清理:如果没有剩余会话,移除 login_id 条目
967                if session_ids.is_empty() {
968                    index.remove(&session.login_id);
969                }
970            }
971        }
972        Ok(())
973    }
974
975    /// Get all sessions for a user | 获取用户的所有会话
976    ///
977    /// # Implementation Details | 实现细节
978    ///
979    /// 1. Looks up session_ids in login_index
980    ///    在 login_index 中查找 session_ids
981    /// 2. Retrieves full session data for each session_id
982    ///    为每个 session_id 检索完整的会话数据
983    /// 3. Filters out any missing sessions (cleanup)
984    ///    过滤掉任何缺失的会话(清理)
985    ///
986    /// # Returns | 返回
987    ///
988    /// Vector of all active sessions for the user
989    /// 用户所有活跃会话的向量
990    async fn get_sessions_by_login_id(&self, login_id: &str) -> Result<Vec<DistributedSession>, SaTokenError> {
991        // 1. Get session IDs from index
992        // 从索引中获取会话 IDs
993        let index = self.login_index.read().await;
994        let session_ids = index.get(login_id).cloned().unwrap_or_default();
995        
996        // 2. Retrieve full session data
997        // 检索完整的会话数据
998        let sessions = self.sessions.read().await;
999        let mut result = Vec::new();
1000        
1001        for session_id in session_ids {
1002            if let Some(session) = sessions.get(&session_id) {
1003                result.push(session.clone());
1004            }
1005            // Note: If session not found, it was deleted but index not updated
1006            // This is a minor inconsistency acceptable in memory storage
1007            // 注意:如果未找到会话,说明会话已删除但索引未更新
1008            // 这是内存存储中可接受的小不一致
1009        }
1010        
1011        Ok(result)
1012    }
1013}
1014
1015#[cfg(test)]
1016mod tests {
1017    use super::*;
1018
1019    #[tokio::test]
1020    async fn test_distributed_session_manager() {
1021        let storage = Arc::new(InMemoryDistributedStorage::new());
1022        let manager = DistributedSessionManager::new(
1023            storage,
1024            "service1".to_string(),
1025            Duration::from_secs(3600),
1026        );
1027
1028        let session = manager.create_session(
1029            "user1".to_string(),
1030            "token1".to_string(),
1031        ).await.unwrap();
1032
1033        let retrieved = manager.get_session(&session.session_id).await.unwrap();
1034        assert_eq!(retrieved.login_id, "user1");
1035    }
1036
1037    #[tokio::test]
1038    async fn test_session_attributes() {
1039        let storage = Arc::new(InMemoryDistributedStorage::new());
1040        let manager = DistributedSessionManager::new(
1041            storage,
1042            "service1".to_string(),
1043            Duration::from_secs(3600),
1044        );
1045
1046        let session = manager.create_session(
1047            "user2".to_string(),
1048            "token2".to_string(),
1049        ).await.unwrap();
1050
1051        manager.set_attribute(
1052            &session.session_id,
1053            "key1".to_string(),
1054            "value1".to_string(),
1055        ).await.unwrap();
1056
1057        let value = manager.get_attribute(&session.session_id, "key1").await.unwrap();
1058        assert_eq!(value, Some("value1".to_string()));
1059    }
1060
1061    #[tokio::test]
1062    async fn test_service_verification() {
1063        let storage = Arc::new(InMemoryDistributedStorage::new());
1064        let manager = DistributedSessionManager::new(
1065            storage,
1066            "service1".to_string(),
1067            Duration::from_secs(3600),
1068        );
1069
1070        let credential = ServiceCredential {
1071            service_id: "service2".to_string(),
1072            service_name: "Service 2".to_string(),
1073            secret_key: "secret123".to_string(),
1074            created_at: Utc::now(),
1075            permissions: vec!["read".to_string(), "write".to_string()],
1076        };
1077
1078        manager.register_service(credential.clone()).await;
1079
1080        let verified = manager.verify_service("service2", "secret123").await.unwrap();
1081        assert_eq!(verified.service_id, "service2");
1082
1083        let result = manager.verify_service("service2", "wrong_secret").await;
1084        assert!(result.is_err());
1085    }
1086
1087    #[tokio::test]
1088    async fn test_delete_all_sessions() {
1089        let storage = Arc::new(InMemoryDistributedStorage::new());
1090        let manager = DistributedSessionManager::new(
1091            storage,
1092            "service1".to_string(),
1093            Duration::from_secs(3600),
1094        );
1095
1096        manager.create_session("user3".to_string(), "token1".to_string()).await.unwrap();
1097        manager.create_session("user3".to_string(), "token2".to_string()).await.unwrap();
1098
1099        let sessions = manager.get_sessions_by_login_id("user3").await.unwrap();
1100        assert_eq!(sessions.len(), 2);
1101
1102        manager.delete_all_sessions("user3").await.unwrap();
1103
1104        let sessions = manager.get_sessions_by_login_id("user3").await.unwrap();
1105        assert_eq!(sessions.len(), 0);
1106    }
1107}