sa_token_core/
config.rs

1// Author: 金书记
2//
3//! 配置模块
4
5use std::time::Duration;
6use std::sync::Arc;
7use serde::{Deserialize, Serialize};
8use sa_token_adapter::storage::SaStorage;
9
10/// sa-token 配置
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct SaTokenConfig {
13    /// Token 名称(例如在 header 或 cookie 中的键名)
14    pub token_name: String,
15    
16    /// Token 有效期(秒),-1 表示永久有效
17    pub timeout: i64,
18    
19    /// Token 最低活跃频率(秒),-1 表示不限制
20    /// 
21    /// 配合 auto_renew 使用时,表示自动续签的时长
22    pub active_timeout: i64,
23    
24    /// 是否开启自动续签(默认 false)
25    /// 
26    /// 如果设置为 true,在以下场景会自动续签 token:
27    /// - 调用 get_token_info() 时
28    /// - 中间件验证 token 时
29    /// - 调用无参数的 StpUtil 方法时
30    /// 
31    /// 续签时长由 active_timeout 决定:
32    /// - 如果 active_timeout > 0,则续签 active_timeout 秒
33    /// - 如果 active_timeout <= 0,则续签 timeout 秒
34    pub auto_renew: bool,
35    
36    /// 是否允许同一账号并发登录
37    pub is_concurrent: bool,
38    
39    /// 在多人登录同一账号时,是否共享一个 token
40    pub is_share: bool,
41    
42    /// Token 风格(uuid、simple-uuid、random-32、random-64、random-128)
43    pub token_style: TokenStyle,
44    
45    /// 是否输出操作日志
46    pub is_log: bool,
47    
48    /// 是否从 cookie 中读取 token
49    pub is_read_cookie: bool,
50    
51    /// 是否从 header 中读取 token
52    pub is_read_header: bool,
53    
54    /// 是否从请求体中读取 token
55    pub is_read_body: bool,
56    
57    /// token 前缀(例如 "Bearer ")
58    pub token_prefix: Option<String>,
59    
60    /// JWT 密钥(如果使用 JWT)
61    pub jwt_secret_key: Option<String>,
62}
63
64impl Default for SaTokenConfig {
65    fn default() -> Self {
66        Self {
67            token_name: "sa-token".to_string(),
68            timeout: 2592000, // 30天
69            active_timeout: -1,
70            auto_renew: false, // 默认不开启自动续签
71            is_concurrent: true,
72            is_share: true,
73            token_style: TokenStyle::Uuid,
74            is_log: false,
75            is_read_cookie: true,
76            is_read_header: true,
77            is_read_body: false,
78            token_prefix: None,
79            jwt_secret_key: None,
80        }
81    }
82}
83
84impl SaTokenConfig {
85    pub fn builder() -> SaTokenConfigBuilder {
86        SaTokenConfigBuilder::default()
87    }
88    
89    pub fn timeout_duration(&self) -> Option<Duration> {
90        if self.timeout < 0 {
91            None
92        } else {
93            Some(Duration::from_secs(self.timeout as u64))
94        }
95    }
96}
97
98/// Token 风格
99#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
100pub enum TokenStyle {
101    /// UUID 风格
102    Uuid,
103    /// 简化的 UUID(去掉横杠)
104    SimpleUuid,
105    /// 32位随机字符串
106    Random32,
107    /// 64位随机字符串
108    Random64,
109    /// 128位随机字符串
110    Random128,
111}
112
113/// 配置构建器
114pub struct SaTokenConfigBuilder {
115    config: SaTokenConfig,
116    storage: Option<Arc<dyn SaStorage>>,
117}
118
119impl Default for SaTokenConfigBuilder {
120    fn default() -> Self {
121        Self {
122            config: SaTokenConfig::default(),
123            storage: None,
124        }
125    }
126}
127
128impl SaTokenConfigBuilder {
129    pub fn token_name(mut self, name: impl Into<String>) -> Self {
130        self.config.token_name = name.into();
131        self
132    }
133    
134    pub fn timeout(mut self, timeout: i64) -> Self {
135        self.config.timeout = timeout;
136        self
137    }
138    
139    pub fn active_timeout(mut self, timeout: i64) -> Self {
140        self.config.active_timeout = timeout;
141        self
142    }
143    
144    /// 设置是否开启自动续签
145    pub fn auto_renew(mut self, enabled: bool) -> Self {
146        self.config.auto_renew = enabled;
147        self
148    }
149    
150    pub fn is_concurrent(mut self, concurrent: bool) -> Self {
151        self.config.is_concurrent = concurrent;
152        self
153    }
154    
155    pub fn is_share(mut self, share: bool) -> Self {
156        self.config.is_share = share;
157        self
158    }
159    
160    pub fn token_style(mut self, style: TokenStyle) -> Self {
161        self.config.token_style = style;
162        self
163    }
164    
165    pub fn token_prefix(mut self, prefix: impl Into<String>) -> Self {
166        self.config.token_prefix = Some(prefix.into());
167        self
168    }
169    
170    pub fn jwt_secret_key(mut self, key: impl Into<String>) -> Self {
171        self.config.jwt_secret_key = Some(key.into());
172        self
173    }
174    
175    /// 设置存储方式
176    pub fn storage(mut self, storage: Arc<dyn SaStorage>) -> Self {
177        self.storage = Some(storage);
178        self
179    }
180    
181    /// 构建 SaTokenManager(需要先设置 storage)
182    /// 
183    /// # Panics
184    /// 如果未设置 storage,会 panic
185    /// 
186    /// # 示例
187    /// ```rust,ignore
188    /// use std::sync::Arc;
189    /// use sa_token_core::SaTokenConfig;
190    /// use sa_token_storage_memory::MemoryStorage;
191    /// 
192    /// let manager = SaTokenConfig::builder()
193    ///     .storage(Arc::new(MemoryStorage::new()))
194    ///     .timeout(7200)
195    ///     .build();
196    /// ```
197    pub fn build(self) -> crate::SaTokenManager {
198        let storage = self.storage.expect("Storage must be set before building SaTokenManager. Use .storage() method.");
199        crate::SaTokenManager::new(storage, self.config)
200    }
201    
202    /// 仅构建配置(不创建 Manager)
203    pub fn build_config(self) -> SaTokenConfig {
204        self.config
205    }
206}