Module distributed

Module distributed 

Source
Expand description

Distributed Session Management Module | 分布式 Session 管理模块

§Overview | 概述

This module enables distributed session management for microservices architecture, allowing multiple services to share authentication sessions seamlessly. 本模块为微服务架构提供分布式 Session 管理,允许多个服务无缝共享认证会话。

§Architecture Context | 架构上下文

┌────────────────────────────────────────────────────────────────────┐
│                   Microservices Architecture                       │
│                   微服务架构                                        │
└────────────────────────────────────────────────────────────────────┘

   ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
   │  Service A   │  │  Service B   │  │  Service C   │
   │  (User API)  │  │  (Order API) │  │  (Pay API)   │
   └──────┬───────┘  └──────┬───────┘  └──────┬───────┘
          │                  │                  │
          └──────────────────┼──────────────────┘
                             │
                   ┌─────────▼──────────┐
                   │  Distributed       │
                   │  Session Storage   │
                   │  (Redis/Database)  │
                   └────────────────────┘

Each service can:
每个服务可以:
  1. Create sessions for users
     为用户创建会话
  2. Access sessions created by other services
     访问其他服务创建的会话
  3. Share user authentication state
     共享用户认证状态

§Key Use Cases | 关键使用场景

§1. Single Sign-On (SSO) Across Services | 跨服务单点登录

Scenario: User logs in to Service A and accesses Service B
场景:用户登录服务 A 并访问服务 B

1. User → Service A: Login
   用户 → 服务 A:登录
   ├─ Service A creates session: session_id = "abc123"
   │  服务 A 创建会话:session_id = "abc123"
   └─ Saves to distributed storage
      保存到分布式存储

2. User → Service B: Request with session_id = "abc123"
   用户 → 服务 B:请求带 session_id = "abc123"
   ├─ Service B retrieves session from storage
   │  服务 B 从存储中获取会话
   ├─ Validates user is authenticated
   │  验证用户已认证
   └─ Processes request ✅
      处理请求 ✅

No need to log in again! 无需再次登录!

§2. Session Sharing for User Context | 会话共享用户上下文

Service A stores: { "user_role": "admin", "department": "IT" }
服务 A 存储:{ "user_role": "admin", "department": "IT" }

Service B reads: Same session attributes available
服务 B 读取:相同的会话属性可用

Service C updates: { "last_order": "order_123" }
服务 C 更新:{ "last_order": "order_123" }

All services share the same session state!
所有服务共享相同的会话状态!

§3. Multi-Device Session Management | 多设备会话管理

User: user_123
  ├─ Session 1: Web (Service A)
  │  会话 1:网页(服务 A)
  ├─ Session 2: Mobile (Service B)
  │  会话 2:移动端(服务 B)
  └─ Session 3: Desktop (Service C)
     会话 3:桌面端(服务 C)

All sessions can be:
所有会话可以:
  - Listed: get_sessions_by_login_id()
  - Managed individually
  - Terminated all at once: delete_all_sessions()

§Integration with Sa-Token | 与 Sa-Token 的集成

┌─────────────────────────────────────────────────────────┐
│               Sa-Token Core Flow                        │
│               Sa-Token 核心流程                          │
└─────────────────────────────────────────────────────────┘

SaTokenManager::login()
  ├─ 1. Generate token
  │     生成 token
  ├─ 2. Create TokenInfo
  │     创建 TokenInfo
  └─ 3. Create DistributedSession (if enabled)
         创建 DistributedSession(如果启用)
         ├─ session_id: UUID
         ├─ login_id: user's login ID
         ├─ token: access token
         ├─ service_id: current service
         └─ attributes: custom data

StpUtil::get_session()
  └─ Retrieves distributed session
     获取分布式会话

StpUtil::logout()
  └─ Deletes distributed session(s)
     删除分布式会话

§Workflow Diagrams | 工作流程图

§Complete Session Lifecycle | 完整会话生命周期

┌──────────────────────────────────────────────────────────────────┐
│                    Session Lifecycle                             │
│                    会话生命周期                                   │
└──────────────────────────────────────────────────────────────────┘

User                Service A           Storage           Service B
用户                服务 A              存储              服务 B
 │                     │                   │                   │
 │  1. Login           │                   │                   │
 │  登录               │                   │                   │
 ├────────────────────▶│                   │                   │
 │                     │  2. create_session()                  │
 │                     │  创建会话          │                   │
 │                     │  ├─ session_id: uuid                  │
 │                     │  ├─ login_id: user_123                │
 │                     │  ├─ token: access_token               │
 │                     │  └─ service_id: service-a             │
 │                     │                   │                   │
 │                     │  3. save_session()│                   │
 │                     │  保存会话          │                   │
 │                     ├──────────────────▶│                   │
 │                     │                   │  Store with TTL   │
 │                     │                   │  存储并设置 TTL    │
 │                     │                   │                   │
 │  4. session_id      │                   │                   │
 │  返回会话 ID        │                   │                   │
 │◀────────────────────│                   │                   │
 │                     │                   │                   │
 │  5. Request to Service B with session_id                    │
 │  带 session_id 请求服务 B                                    │
 ├────────────────────────────────────────────────────────────▶│
 │                     │                   │                   │
 │                     │                   │  6. get_session() │
 │                     │                   │  获取会话          │
 │                     │                   │◀──────────────────│
 │                     │                   │                   │
 │                     │                   │  7. Return session│
 │                     │                   │  返回会话数据      │
 │                     │                   ├──────────────────▶│
 │                     │                   │                   │
 │                     │                   │  8. refresh_session()
 │                     │                   │  刷新会话          │
 │                     │                   │  (update last_access)
 │                     │                   │◀──────────────────│
 │                     │                   │                   │
 │  9. Response        │                   │                   │
 │  响应               │                   │                   │
 │◀────────────────────────────────────────────────────────────│
 │                     │                   │                   │
 │  10. Logout         │                   │                   │
 │  登出               │                   │                   │
 ├────────────────────▶│                   │                   │
 │                     │  11. delete_session()                 │
 │                     │  删除会话          │                   │
 │                     ├──────────────────▶│                   │
 │                     │                   │  Remove from storage
 │                     │                   │  从存储中移除      │
 │                     │                   │                   │
 │  12. Logout Success │                   │                   │
 │  登出成功           │                   │                   │
 │◀────────────────────│                   │                   │
 │                     │                   │                   │

§Service Authentication Flow | 服务认证流程

┌──────────────────────────────────────────────────────────────────┐
│                Service Inter-Communication                       │
│                服务间通信                                         │
└──────────────────────────────────────────────────────────────────┘

Service B          Service A (Session Manager)          Storage
服务 B             服务 A(会话管理器)                  存储
  │                        │                               │
  │  1. Register           │                               │
  │  注册服务              │                               │
  │  ├─ service_id         │                               │
  │  ├─ service_name       │                               │
  │  ├─ secret_key         │                               │
  │  └─ permissions        │                               │
  ├───────────────────────▶│                               │
  │                        │  Store credentials            │
  │                        │  存储凭证                      │
  │                        │  (in memory)                  │
  │                        │                               │
  │  2. Registered ✅      │                               │
  │◀───────────────────────│                               │
  │                        │                               │
  │  3. Access session     │                               │
  │  访问会话              │                               │
  │  ├─ service_id         │                               │
  │  ├─ secret_key         │                               │
  │  └─ session_id         │                               │
  ├───────────────────────▶│                               │
  │                        │  4. verify_service()          │
  │                        │  验证服务                      │
  │                        │  ├─ Lookup service            │
  │                        │  └─ Compare secret_key        │
  │                        │                               │
  │                        │  5. get_session()             │
  │                        │  获取会话                      │
  │                        ├──────────────────────────────▶│
  │                        │                               │
  │                        │  6. Return session            │
  │                        │  返回会话                      │
  │                        │◀──────────────────────────────│
  │                        │                               │
  │  7. Session data ✅    │                               │
  │◀───────────────────────│                               │
  │                        │                               │

§Storage Backends | 存储后端

The module is storage-agnostic. You can implement custom backends: 本模块与存储无关。您可以实现自定义后端:

use redis::AsyncCommands;

pub struct RedisDistributedStorage {
    client: redis::Client,
}

#[async_trait]
impl DistributedSessionStorage for RedisDistributedStorage {
    async fn save_session(&self, session: DistributedSession, ttl: Option<Duration>) 
        -> Result<(), SaTokenError> 
    {
        let mut conn = self.client.get_async_connection().await?;
        let key = format!("distributed:session:{}", session.session_id);
        let value = serde_json::to_string(&session)?;
         
        if let Some(ttl) = ttl {
            conn.set_ex(&key, value, ttl.as_secs() as usize).await?;
        } else {
            conn.set(&key, value).await?;
        }
         
        // Index by login_id
        let index_key = format!("distributed:login:{}", session.login_id);
        conn.sadd(index_key, &session.session_id).await?;
         
        Ok(())
    }
     
    // ... other methods
}

§Database Implementation | 数据库实现

use sqlx::PgPool;

pub struct PostgresDistributedStorage {
    pool: PgPool,
}

#[async_trait]
impl DistributedSessionStorage for PostgresDistributedStorage {
    async fn save_session(&self, session: DistributedSession, ttl: Option<Duration>) 
        -> Result<(), SaTokenError> 
    {
        let expires_at = ttl.map(|t| Utc::now() + chrono::Duration::from_std(t).unwrap());
         
        sqlx::query!(
            "INSERT INTO distributed_sessions 
             (session_id, login_id, token, service_id, attributes, expires_at)
             VALUES ($1, $2, $3, $4, $5, $6)
             ON CONFLICT (session_id) DO UPDATE 
             SET attributes = $5, last_access = NOW()",
            session.session_id,
            session.login_id,
            session.token,
            session.service_id,
            serde_json::to_value(&session.attributes)?,
            expires_at,
        )
        .execute(&self.pool)
        .await?;
         
        Ok(())
    }
     
    // ... other methods
}

§Best Practices | 最佳实践

§1. Service Registration | 服务注册

// Initialize each service with unique credentials
// 为每个服务初始化唯一凭证
let credential = ServiceCredential {
    service_id: "user-service".to_string(),
    service_name: "User Management Service".to_string(),
    secret_key: generate_secure_secret(), // Use crypto-secure generation
    created_at: Utc::now(),
    permissions: vec!["user.read".to_string(), "user.write".to_string()],
};
manager.register_service(credential).await;

§2. Session Creation with Context | 带上下文的会话创建

// Create session with user context
// 创建带用户上下文的会话
let session = manager.create_session(login_id, token).await?;

// Add relevant attributes immediately
// 立即添加相关属性
manager.set_attribute(&session.session_id, "user_role".to_string(), "admin".to_string()).await?;
manager.set_attribute(&session.session_id, "department".to_string(), "IT".to_string()).await?;
manager.set_attribute(&session.session_id, "login_device".to_string(), "web".to_string()).await?;

§3. Cross-Service Access Pattern | 跨服务访问模式

// Service B accesses session created by Service A
// 服务 B 访问服务 A 创建的会话
 
// 1. Verify service identity
// 验证服务身份
let service_cred = manager.verify_service("service-b", request.secret).await?;

// 2. Check permissions
// 检查权限
if !service_cred.permissions.contains(&"session.read".to_string()) {
    return Err(SaTokenError::PermissionDenied);
}

// 3. Access session
// 访问会话
let session = manager.get_session(&request.session_id).await?;

// 4. Refresh to keep session alive
// 刷新以保持会话活跃
manager.refresh_session(&session.session_id).await?;

§4. Multi-Device Logout | 多设备登出

// Logout from all devices
// 从所有设备登出
manager.delete_all_sessions(&login_id).await?;

// Or logout specific session
// 或登出特定会话
manager.delete_session(&session_id).await?;

§5. Session Monitoring | 会话监控

// Monitor user's active sessions
// 监控用户的活跃会话
let sessions = manager.get_sessions_by_login_id(&login_id).await?;
 
for session in sessions {
    println!("Session: {} from service: {}, last active: {}", 
        session.session_id,
        session.service_id,
        session.last_access
    );
     
    // Check for suspicious activity
    // 检查可疑活动
    if is_suspicious(&session) {
        manager.delete_session(&session.session_id).await?;
    }
}

§Security Considerations | 安全考虑

1. ✅ Service Authentication | 服务认证
   - Each service has unique secret_key
   - Verify credentials before granting access
   - Rotate keys periodically

2. ✅ Permission-Based Access | 基于权限的访问
   - Services have explicit permissions
   - Check permissions before operations
   - Implement least-privilege principle

3. ✅ Session Timeout | 会话超时
   - Configure appropriate TTL
   - Auto-expire inactive sessions
   - Refresh on active use

4. ✅ Data Encryption | 数据加密
   - Encrypt sensitive session attributes
   - Use TLS for inter-service communication
   - Encrypt data at rest in storage

5. ✅ Audit Logging | 审计日志
   - Log session creation/deletion
   - Track cross-service access
   - Monitor for anomalies

Structs§

DistributedSession
Distributed session data structure 分布式 Session 数据结构
DistributedSessionManager
Distributed session manager 分布式 Session 管理器
InMemoryDistributedStorage
In-memory distributed session storage implementation 内存分布式 Session 存储实现
ServiceCredential
Service credential for inter-service authentication 服务间认证的服务凭证

Traits§

DistributedSessionStorage
Distributed session storage trait 分布式 Session 存储 trait