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;
9use crate::event::SaTokenListener;
10
11/// sa-token 配置
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SaTokenConfig {
14    /// Token 名称(例如在 header 或 cookie 中的键名)
15    pub token_name: String,
16    
17    /// Token 有效期(秒),-1 表示永久有效
18    pub timeout: i64,
19    
20    /// Token 最低活跃频率(秒),-1 表示不限制
21    /// 
22    /// 配合 auto_renew 使用时,表示自动续签的时长
23    pub active_timeout: i64,
24    
25    /// 是否开启自动续签(默认 false)
26    /// 
27    /// 如果设置为 true,在以下场景会自动续签 token:
28    /// - 调用 get_token_info() 时
29    /// - 中间件验证 token 时
30    /// - 调用无参数的 StpUtil 方法时
31    /// 
32    /// 续签时长由 active_timeout 决定:
33    /// - 如果 active_timeout > 0,则续签 active_timeout 秒
34    /// - 如果 active_timeout <= 0,则续签 timeout 秒
35    pub auto_renew: bool,
36    
37    /// 是否允许同一账号并发登录
38    pub is_concurrent: bool,
39    
40    /// 在多人登录同一账号时,是否共享一个 token
41    pub is_share: bool,
42    
43    /// Token 风格(uuid、simple-uuid、random-32、random-64、random-128)
44    pub token_style: TokenStyle,
45    
46    /// 是否输出操作日志
47    pub is_log: bool,
48    
49    /// 是否从 cookie 中读取 token
50    pub is_read_cookie: bool,
51    
52    /// 是否从 header 中读取 token
53    pub is_read_header: bool,
54    
55    /// 是否从请求体中读取 token
56    pub is_read_body: bool,
57    
58    /// token 前缀(例如 "Bearer ")
59    pub token_prefix: Option<String>,
60    
61    /// JWT 密钥(如果使用 JWT)
62    pub jwt_secret_key: Option<String>,
63    
64    /// JWT 算法(默认 HS256)
65    pub jwt_algorithm: Option<String>,
66    
67    /// JWT 签发者
68    pub jwt_issuer: Option<String>,
69    
70    /// JWT 受众
71    pub jwt_audience: Option<String>,
72    
73    /// 是否启用防重放攻击(nonce 机制)
74    pub enable_nonce: bool,
75    
76    /// Nonce 有效期(秒),-1 表示使用 token timeout
77    pub nonce_timeout: i64,
78    
79    /// 是否启用 Refresh Token
80    pub enable_refresh_token: bool,
81    
82    /// Refresh Token 有效期(秒),默认 7 天
83    pub refresh_token_timeout: i64,
84}
85
86impl Default for SaTokenConfig {
87    fn default() -> Self {
88        Self {
89            token_name: "sa-token".to_string(),
90            timeout: 2592000, // 30天
91            active_timeout: -1,
92            auto_renew: false, // 默认不开启自动续签
93            is_concurrent: true,
94            is_share: true,
95            token_style: TokenStyle::Uuid,
96            is_log: false,
97            is_read_cookie: true,
98            is_read_header: true,
99            is_read_body: false,
100            token_prefix: None,
101            jwt_secret_key: None,
102            jwt_algorithm: Some("HS256".to_string()),
103            jwt_issuer: None,
104            jwt_audience: None,
105            enable_nonce: false,
106            nonce_timeout: -1,
107            enable_refresh_token: false,
108            refresh_token_timeout: 604800, // 7 天
109        }
110    }
111}
112
113impl SaTokenConfig {
114    pub fn builder() -> SaTokenConfigBuilder {
115        SaTokenConfigBuilder::default()
116    }
117    
118    pub fn timeout_duration(&self) -> Option<Duration> {
119        if self.timeout < 0 {
120            None
121        } else {
122            Some(Duration::from_secs(self.timeout as u64))
123        }
124    }
125}
126
127/// Token 风格 | Token Style
128#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
129pub enum TokenStyle {
130    /// UUID 风格 | UUID style
131    Uuid,
132    /// 简化的 UUID(去掉横杠)| Simple UUID (without hyphens)
133    SimpleUuid,
134    /// 32位随机字符串 | 32-character random string
135    Random32,
136    /// 64位随机字符串 | 64-character random string
137    Random64,
138    /// 128位随机字符串 | 128-character random string
139    Random128,
140    /// JWT 风格(JSON Web Token)| JWT style (JSON Web Token)
141    Jwt,
142    /// Hash 风格(SHA256哈希)| Hash style (SHA256 hash)
143    Hash,
144    /// 时间戳风格(毫秒级时间戳+随机数)| Timestamp style (millisecond timestamp + random)
145    Timestamp,
146    /// Tik 风格(短小精悍的8位字符)| Tik style (short 8-character token)
147    Tik,
148}
149
150/// 配置构建器
151pub struct SaTokenConfigBuilder {
152    config: SaTokenConfig,
153    storage: Option<Arc<dyn SaStorage>>,
154    listeners: Vec<Arc<dyn SaTokenListener>>,
155}
156
157impl Default for SaTokenConfigBuilder {
158    fn default() -> Self {
159        Self {
160            config: SaTokenConfig::default(),
161            storage: None,
162            listeners: Vec::new(),
163        }
164    }
165}
166
167impl SaTokenConfigBuilder {
168    pub fn token_name(mut self, name: impl Into<String>) -> Self {
169        self.config.token_name = name.into();
170        self
171    }
172    
173    pub fn timeout(mut self, timeout: i64) -> Self {
174        self.config.timeout = timeout;
175        self
176    }
177    
178    pub fn active_timeout(mut self, timeout: i64) -> Self {
179        self.config.active_timeout = timeout;
180        self
181    }
182    
183    /// 设置是否开启自动续签
184    pub fn auto_renew(mut self, enabled: bool) -> Self {
185        self.config.auto_renew = enabled;
186        self
187    }
188    
189    pub fn is_concurrent(mut self, concurrent: bool) -> Self {
190        self.config.is_concurrent = concurrent;
191        self
192    }
193    
194    pub fn is_share(mut self, share: bool) -> Self {
195        self.config.is_share = share;
196        self
197    }
198    
199    pub fn token_style(mut self, style: TokenStyle) -> Self {
200        self.config.token_style = style;
201        self
202    }
203    
204    pub fn token_prefix(mut self, prefix: impl Into<String>) -> Self {
205        self.config.token_prefix = Some(prefix.into());
206        self
207    }
208    
209    pub fn jwt_secret_key(mut self, key: impl Into<String>) -> Self {
210        self.config.jwt_secret_key = Some(key.into());
211        self
212    }
213    
214    /// 设置 JWT 算法
215    pub fn jwt_algorithm(mut self, algorithm: impl Into<String>) -> Self {
216        self.config.jwt_algorithm = Some(algorithm.into());
217        self
218    }
219    
220    /// 设置 JWT 签发者
221    pub fn jwt_issuer(mut self, issuer: impl Into<String>) -> Self {
222        self.config.jwt_issuer = Some(issuer.into());
223        self
224    }
225    
226    /// 设置 JWT 受众
227    pub fn jwt_audience(mut self, audience: impl Into<String>) -> Self {
228        self.config.jwt_audience = Some(audience.into());
229        self
230    }
231    
232    /// 启用防重放攻击(nonce 机制)
233    pub fn enable_nonce(mut self, enable: bool) -> Self {
234        self.config.enable_nonce = enable;
235        self
236    }
237    
238    /// 设置 Nonce 有效期(秒)
239    pub fn nonce_timeout(mut self, timeout: i64) -> Self {
240        self.config.nonce_timeout = timeout;
241        self
242    }
243    
244    /// 启用 Refresh Token
245    pub fn enable_refresh_token(mut self, enable: bool) -> Self {
246        self.config.enable_refresh_token = enable;
247        self
248    }
249    
250    /// 设置 Refresh Token 有效期(秒)
251    pub fn refresh_token_timeout(mut self, timeout: i64) -> Self {
252        self.config.refresh_token_timeout = timeout;
253        self
254    }
255    
256    /// 设置存储方式
257    pub fn storage(mut self, storage: Arc<dyn SaStorage>) -> Self {
258        self.storage = Some(storage);
259        self
260    }
261    
262    /// 注册事件监听器
263    /// 
264    /// 可以多次调用以注册多个监听器
265    /// 
266    /// # 示例
267    /// ```rust,ignore
268    /// use std::sync::Arc;
269    /// use sa_token_core::{SaTokenConfig, SaTokenListener};
270    /// 
271    /// struct MyListener;
272    /// impl SaTokenListener for MyListener { /* ... */ }
273    /// 
274    /// let manager = SaTokenConfig::builder()
275    ///     .storage(Arc::new(MemoryStorage::new()))
276    ///     .register_listener(Arc::new(MyListener))
277    ///     .build();
278    /// ```
279    pub fn register_listener(mut self, listener: Arc<dyn SaTokenListener>) -> Self {
280        self.listeners.push(listener);
281        self
282    }
283    
284    /// 构建 SaTokenManager(需要先设置 storage)
285    /// 
286    /// 自动完成以下操作:
287    /// 1. 创建 SaTokenManager
288    /// 2. 注册所有事件监听器
289    /// 3. 初始化 StpUtil
290    /// 
291    /// Auto-complete the following operations:
292    /// 1. Create SaTokenManager
293    /// 2. Register all event listeners
294    /// 3. Initialize StpUtil
295    /// 
296    /// # Panics
297    /// 如果未设置 storage,会 panic
298    /// 
299    /// # 示例
300    /// ```rust,ignore
301    /// use std::sync::Arc;
302    /// use sa_token_core::SaTokenConfig;
303    /// use sa_token_storage_memory::MemoryStorage;
304    /// 
305    /// // 一行代码完成所有初始化!
306    /// // Complete all initialization in one line!
307    /// SaTokenConfig::builder()
308    ///     .storage(Arc::new(MemoryStorage::new()))
309    ///     .timeout(7200)
310    ///     .register_listener(Arc::new(MyListener))
311    ///     .build();  // 自动初始化 StpUtil!
312    /// ```
313    pub fn build(self) -> crate::SaTokenManager {
314        let storage = self.storage.expect("Storage must be set before building SaTokenManager. Use .storage() method.");
315        let manager = crate::SaTokenManager::new(storage, self.config);
316        
317        // 同步注册所有监听器
318        // Register all listeners synchronously
319        if !self.listeners.is_empty() {
320            let event_bus = manager.event_bus();
321            for listener in self.listeners {
322                event_bus.register(listener);
323            }
324        }
325        
326        // 自动初始化 StpUtil
327        // Auto-initialize StpUtil
328        crate::StpUtil::init_manager(manager.clone());
329        
330        manager
331    }
332    
333    /// 仅构建配置(不创建 Manager)
334    pub fn build_config(self) -> SaTokenConfig {
335        self.config
336    }
337}