authrs/token/
refresh.rs

1//! Refresh Token 实现模块
2//!
3//! 提供 Refresh Token 的生成、验证、存储和轮换功能。
4//!
5//! ## 特性
6//!
7//! - 安全的 Refresh Token 生成
8//! - Token 轮换(每次使用后生成新 Token)
9//! - Token 家族追踪(检测 Token 重用攻击)
10//! - 可配置的过期策略
11//! - 灵活的元数据存储
12//!
13//! ## 示例
14//!
15//! ```rust
16//! # tokio::runtime::Runtime::new().unwrap().block_on(async {
17//! use authrs::token::refresh::{RefreshTokenManager, RefreshConfig};
18//!
19//! // 创建 Refresh Token 管理器
20//! let config = RefreshConfig::default();
21//! let manager = RefreshTokenManager::new(config);
22//!
23//! // 生成 Refresh Token
24//! let token = manager.generate("user123").await.unwrap();
25//! println!("Token: {}", token.token);
26//!
27//! // 使用 Refresh Token(会自动轮换)
28//! let result = manager.use_token(&token.token).await.unwrap();
29//! if let Some(new_token) = result.new_token {
30//!     println!("New Token: {}", new_token.token);
31//! }
32//! # });
33//! ```
34//!
35//! ## 自定义存储后端
36//!
37//! 实现 `RefreshTokenStore` trait 可以使用自定义的存储后端:
38//!
39//! ```rust,ignore
40//! use authrs::token::refresh::{RefreshToken, RefreshTokenStore, RefreshTokenManager, RefreshConfig};
41//! use authrs::error::Result;
42//! use std::sync::Arc;
43//!
44//! struct RedisRefreshTokenStore {
45//!     // Redis 连接
46//! }
47//!
48//! impl RefreshTokenStore for RedisRefreshTokenStore {
49//!     fn save(&self, token: &RefreshToken) -> Result<()> {
50//!         // 保存到 Redis
51//!         todo!()
52//!     }
53//!     // ... 实现其他方法
54//! }
55//!
56//! // 使用自定义存储
57//! let store = Arc::new(RedisRefreshTokenStore { /* ... */ });
58//! let manager = RefreshTokenManager::with_store(RefreshConfig::default(), store);
59//! ```
60
61use async_trait::async_trait;
62use chrono::{Duration, Utc};
63use serde::{Deserialize, Serialize, de::DeserializeOwned};
64use std::collections::HashMap;
65use std::sync::{Arc, RwLock};
66
67use crate::error::{Error, Result, StorageError, TokenError};
68use crate::random::{generate_random_base64_url, generate_random_hex};
69
70// ============================================================================
71// Refresh Token 数据结构
72// ============================================================================
73
74/// Refresh Token 数据结构
75///
76/// 包含 Token 的核心字段和可扩展的元数据。
77///
78/// ## Token 家族
79///
80/// `family_id` 用于追踪 Token 的血缘关系。当 Token 轮换时,新旧 Token 共享同一个 family_id。
81/// 如果检测到一个已使用的 Token 被再次使用(重用攻击),可以通过 family_id 撤销整个家族的所有 Token。
82///
83/// ## 元数据
84///
85/// `metadata` 字段允许存储任意可序列化的数据:
86///
87/// ```rust
88/// use authrs::token::refresh::{RefreshTokenManager, RefreshConfig};
89/// use serde::{Serialize, Deserialize};
90///
91/// let manager = RefreshTokenManager::new(RefreshConfig::default());
92/// # tokio::runtime::Runtime::new().unwrap().block_on(async {
93/// let mut token = manager.generate("user123").await.unwrap();
94///
95/// // 存储设备信息
96/// token.set_metadata("device_type", "mobile");
97/// token.set_metadata("app_version", "1.0.0");
98///
99/// // 类型安全地读取
100/// let device: Option<String> = token.get_metadata("device_type");
101/// # });
102/// ```
103#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct RefreshToken {
105    /// Token 值(用于传输和验证)
106    pub token: String,
107
108    /// Token ID(用于存储和查找)
109    pub token_id: String,
110
111    /// 关联的用户 ID
112    pub user_id: String,
113
114    /// Token 家族 ID(用于检测重用攻击)
115    pub family_id: String,
116
117    /// 创建时间(Unix 时间戳,秒)
118    pub created_at: i64,
119
120    /// 过期时间(Unix 时间戳,秒)
121    pub expires_at: i64,
122
123    /// 是否已被使用(用于检测重用)
124    pub used: bool,
125
126    /// 使用时间(Unix 时间戳,秒)
127    pub used_at: Option<i64>,
128
129    /// 替代此 Token 的新 Token ID
130    pub replaced_by: Option<String>,
131
132    /// 设备信息(可选)
133    pub device_info: Option<String>,
134
135    /// IP 地址(可选)
136    pub ip_address: Option<String>,
137
138    /// 用户自定义元数据
139    pub metadata: serde_json::Value,
140}
141
142impl RefreshToken {
143    /// 创建新的 Refresh Token
144    fn new(user_id: impl Into<String>, family_id: String, expires_in: Duration) -> Result<Self> {
145        let now = Utc::now().timestamp();
146        let token = generate_random_base64_url(48)?;
147        let token_id = generate_random_hex(16)?;
148
149        Ok(Self {
150            token,
151            token_id,
152            user_id: user_id.into(),
153            family_id,
154            created_at: now,
155            expires_at: now + expires_in.num_seconds(),
156            used: false,
157            used_at: None,
158            replaced_by: None,
159            device_info: None,
160            ip_address: None,
161            metadata: serde_json::Value::Object(serde_json::Map::new()),
162        })
163    }
164
165    /// 检查 Token 是否已过期
166    #[inline]
167    pub fn is_expired(&self) -> bool {
168        Utc::now().timestamp() > self.expires_at
169    }
170
171    /// 检查 Token 是否有效(未过期且未被使用)
172    #[inline]
173    pub fn is_valid(&self) -> bool {
174        !self.is_expired() && !self.used
175    }
176
177    /// 获取剩余有效时间(秒)
178    ///
179    /// 如果已过期,返回 0
180    pub fn time_to_live(&self) -> i64 {
181        (self.expires_at - Utc::now().timestamp()).max(0)
182    }
183
184    /// 标记 Token 为已使用
185    fn mark_as_used(&mut self, replaced_by: Option<String>) {
186        self.used = true;
187        self.used_at = Some(Utc::now().timestamp());
188        self.replaced_by = replaced_by;
189    }
190
191    // ========================================================================
192    // 元数据访问方法
193    // ========================================================================
194
195    /// 设置元数据
196    ///
197    /// 可以存储任意可序列化的值。如果序列化失败,操作将被忽略。
198    ///
199    /// # 示例
200    ///
201    /// ```rust
202    /// # tokio::runtime::Runtime::new().unwrap().block_on(async {
203    /// use authrs::token::refresh::{RefreshTokenManager, RefreshConfig};
204    ///
205    /// let manager = RefreshTokenManager::new(RefreshConfig::default());
206    /// let mut token = manager.generate("user123").await.unwrap();
207    ///
208    /// token.set_metadata("device", "iPhone");
209    /// token.set_metadata("login_count", 5);
210    /// # });
211    /// ```
212    pub fn set_metadata<T: Serialize>(&mut self, key: impl Into<String>, value: T) {
213        if let Ok(json_value) = serde_json::to_value(value)
214            && let Some(obj) = self.metadata.as_object_mut()
215        {
216            obj.insert(key.into(), json_value);
217        }
218    }
219
220    /// 获取元数据
221    ///
222    /// 类型安全地获取指定键的值。如果键不存在或类型不匹配,返回 `None`。
223    ///
224    /// # 示例
225    ///
226    /// ```rust
227    /// # tokio::runtime::Runtime::new().unwrap().block_on(async {
228    /// use authrs::token::refresh::{RefreshTokenManager, RefreshConfig};
229    ///
230    /// let manager = RefreshTokenManager::new(RefreshConfig::default());
231    /// let mut token = manager.generate("user123").await.unwrap();
232    ///
233    /// token.set_metadata("device", "iPhone");
234    /// let device: Option<String> = token.get_metadata("device");
235    /// assert_eq!(device, Some("iPhone".to_string()));
236    /// # });
237    /// ```
238    pub fn get_metadata<T: DeserializeOwned>(&self, key: &str) -> Option<T> {
239        self.metadata
240            .get(key)
241            .and_then(|v| serde_json::from_value(v.clone()).ok())
242    }
243
244    /// 获取元数据的原始 JSON 值
245    pub fn get_metadata_raw(&self, key: &str) -> Option<&serde_json::Value> {
246        self.metadata.get(key)
247    }
248
249    /// 检查是否存在指定的元数据键
250    pub fn has_metadata(&self, key: &str) -> bool {
251        self.metadata.get(key).is_some()
252    }
253
254    /// 删除元数据
255    ///
256    /// 返回被删除的值(如果存在)
257    pub fn remove_metadata(&mut self, key: &str) -> Option<serde_json::Value> {
258        self.metadata
259            .as_object_mut()
260            .and_then(|obj| obj.remove(key))
261    }
262
263    /// 清空所有元数据
264    pub fn clear_metadata(&mut self) {
265        self.metadata = serde_json::Value::Object(serde_json::Map::new());
266    }
267
268    /// 获取所有元数据键
269    pub fn metadata_keys(&self) -> Vec<&str> {
270        self.metadata
271            .as_object()
272            .map(|obj| obj.keys().map(|k| k.as_str()).collect())
273            .unwrap_or_default()
274    }
275}
276
277// ============================================================================
278// Refresh Token 配置
279// ============================================================================
280
281/// Refresh Token 配置
282#[derive(Debug, Clone)]
283pub struct RefreshConfig {
284    /// Token 有效期
285    pub expiration: Duration,
286
287    /// 是否启用 Token 轮换
288    pub rotation_enabled: bool,
289
290    /// 是否启用重用检测
291    pub reuse_detection: bool,
292
293    /// 每个家族最大 Token 数
294    pub max_tokens_per_family: usize,
295
296    /// 每个用户最大 Token 家族数
297    pub max_families_per_user: usize,
298
299    /// 宽限期(Token 被使用后仍可在宽限期内使用)
300    pub grace_period: Duration,
301}
302
303impl Default for RefreshConfig {
304    fn default() -> Self {
305        Self {
306            expiration: Duration::days(30),
307            rotation_enabled: true,
308            reuse_detection: true,
309            max_tokens_per_family: 5,
310            max_families_per_user: 5,
311            grace_period: Duration::seconds(0),
312        }
313    }
314}
315
316impl RefreshConfig {
317    /// 创建新的配置
318    pub fn new() -> Self {
319        Self::default()
320    }
321
322    /// 设置有效期
323    pub fn with_expiration(mut self, duration: Duration) -> Self {
324        self.expiration = duration;
325        self
326    }
327
328    /// 设置是否启用 Token 轮换
329    pub fn with_rotation(mut self, enabled: bool) -> Self {
330        self.rotation_enabled = enabled;
331        self
332    }
333
334    /// 设置是否启用重用检测
335    pub fn with_reuse_detection(mut self, enabled: bool) -> Self {
336        self.reuse_detection = enabled;
337        self
338    }
339
340    /// 设置每个用户最大 Token 家族数
341    pub fn with_max_families_per_user(mut self, max: usize) -> Self {
342        self.max_families_per_user = max;
343        self
344    }
345
346    /// 设置宽限期
347    pub fn with_grace_period(mut self, duration: Duration) -> Self {
348        self.grace_period = duration;
349        self
350    }
351
352    /// 创建高安全配置
353    ///
354    /// - 7 天有效期
355    /// - 启用 Token 轮换
356    /// - 启用重用检测
357    /// - 无宽限期
358    pub fn high_security() -> Self {
359        Self {
360            expiration: Duration::days(7),
361            rotation_enabled: true,
362            reuse_detection: true,
363            max_tokens_per_family: 3,
364            max_families_per_user: 3,
365            grace_period: Duration::seconds(0),
366        }
367    }
368
369    /// 创建宽松配置
370    ///
371    /// - 90 天有效期
372    /// - 禁用 Token 轮换
373    /// - 禁用重用检测
374    pub fn relaxed() -> Self {
375        Self {
376            expiration: Duration::days(90),
377            rotation_enabled: false,
378            reuse_detection: false,
379            max_tokens_per_family: 10,
380            max_families_per_user: 10,
381            grace_period: Duration::seconds(60),
382        }
383    }
384}
385
386// ============================================================================
387// Refresh Token 存储 Trait
388// ============================================================================
389
390/// Refresh Token 存储 trait
391///
392/// 实现此 trait 可以自定义 Token 的存储后端。
393///
394/// ## 内置实现
395///
396/// - `InMemoryRefreshTokenStore`: 内存存储,适用于开发和测试
397///
398/// ## 自定义实现示例
399///
400/// ```rust,ignore
401/// use authrs::token::refresh::{RefreshToken, RefreshTokenStore};
402/// use authrs::error::Result;
403///
404/// struct PostgresRefreshTokenStore {
405///     pool: sqlx::PgPool,
406/// }
407///
408/// impl RefreshTokenStore for PostgresRefreshTokenStore {
409///     fn save(&self, token: &RefreshToken) -> Result<()> {
410///         // INSERT INTO refresh_tokens ...
411///         todo!()
412///     }
413///
414///     fn get_by_token(&self, token: &str) -> Result<Option<RefreshToken>> {
415///         // SELECT * FROM refresh_tokens WHERE token = ?
416///         todo!()
417///     }
418///
419///     // ... 实现其他方法
420/// }
421/// ```
422#[async_trait]
423pub trait RefreshTokenStore: Send + Sync {
424    /// 保存 Token
425    async fn save(&self, token: &RefreshToken) -> Result<()>;
426
427    /// 通过 Token 值获取 Token
428    async fn get_by_token(&self, token: &str) -> Result<Option<RefreshToken>>;
429
430    /// 通过 Token ID 获取 Token
431    async fn get_by_id(&self, token_id: &str) -> Result<Option<RefreshToken>>;
432
433    /// 更新 Token
434    async fn update(&self, token: &RefreshToken) -> Result<()>;
435
436    /// 删除 Token
437    async fn delete(&self, token_id: &str) -> Result<()>;
438
439    /// 获取用户的所有 Token
440    async fn get_by_user(&self, user_id: &str) -> Result<Vec<RefreshToken>>;
441
442    /// 获取 Token 家族的所有 Token
443    async fn get_by_family(&self, family_id: &str) -> Result<Vec<RefreshToken>>;
444
445    /// 删除 Token 家族的所有 Token
446    ///
447    /// 返回删除的 Token 数量
448    async fn delete_family(&self, family_id: &str) -> Result<usize>;
449
450    /// 删除用户的所有 Token
451    ///
452    /// 返回删除的 Token 数量
453    async fn delete_by_user(&self, user_id: &str) -> Result<usize>;
454
455    /// 清理过期的 Token
456    ///
457    /// 返回清理的 Token 数量
458    async fn cleanup_expired(&self) -> Result<usize>;
459
460    /// 获取 Token 总数
461    async fn count(&self) -> Result<usize>;
462}
463
464// ============================================================================
465// 内存存储实现
466// ============================================================================
467
468/// 内存 Refresh Token 存储
469///
470/// 用于开发和测试,生产环境建议使用 Redis 等持久化存储。
471///
472/// ## 特点
473///
474/// - 线程安全(使用 `RwLock`)
475/// - 维护 Token 值到 Token ID 的索引以加速查找
476/// - 无持久化,重启后数据丢失
477#[derive(Debug, Default)]
478pub struct InMemoryRefreshTokenStore {
479    tokens: RwLock<HashMap<String, RefreshToken>>,
480    token_index: RwLock<HashMap<String, String>>, // token -> token_id
481}
482
483impl InMemoryRefreshTokenStore {
484    /// 创建新的内存存储
485    pub fn new() -> Self {
486        Self::default()
487    }
488}
489
490#[async_trait]
491impl RefreshTokenStore for InMemoryRefreshTokenStore {
492    async fn save(&self, token: &RefreshToken) -> Result<()> {
493        let mut tokens = self
494            .tokens
495            .write()
496            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
497        let mut index = self
498            .token_index
499            .write()
500            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
501
502        index.insert(token.token.clone(), token.token_id.clone());
503        tokens.insert(token.token_id.clone(), token.clone());
504        Ok(())
505    }
506
507    async fn get_by_token(&self, token: &str) -> Result<Option<RefreshToken>> {
508        let index = self
509            .token_index
510            .read()
511            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
512        let tokens = self
513            .tokens
514            .read()
515            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
516
517        if let Some(token_id) = index.get(token) {
518            Ok(tokens.get(token_id).cloned())
519        } else {
520            Ok(None)
521        }
522    }
523
524    async fn get_by_id(&self, token_id: &str) -> Result<Option<RefreshToken>> {
525        let tokens = self
526            .tokens
527            .read()
528            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
529        Ok(tokens.get(token_id).cloned())
530    }
531
532    async fn update(&self, token: &RefreshToken) -> Result<()> {
533        let mut tokens = self
534            .tokens
535            .write()
536            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
537
538        if tokens.contains_key(&token.token_id) {
539            tokens.insert(token.token_id.clone(), token.clone());
540            Ok(())
541        } else {
542            Err(Error::Storage(StorageError::NotFound(
543                "token not found".into(),
544            )))
545        }
546    }
547
548    async fn delete(&self, token_id: &str) -> Result<()> {
549        let mut tokens = self
550            .tokens
551            .write()
552            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
553        let mut index = self
554            .token_index
555            .write()
556            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
557
558        if let Some(token) = tokens.remove(token_id) {
559            index.remove(&token.token);
560        }
561        Ok(())
562    }
563
564    async fn get_by_user(&self, user_id: &str) -> Result<Vec<RefreshToken>> {
565        let tokens = self
566            .tokens
567            .read()
568            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
569
570        Ok(tokens
571            .values()
572            .filter(|t| t.user_id == user_id)
573            .cloned()
574            .collect())
575    }
576
577    async fn get_by_family(&self, family_id: &str) -> Result<Vec<RefreshToken>> {
578        let tokens = self
579            .tokens
580            .read()
581            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
582
583        Ok(tokens
584            .values()
585            .filter(|t| t.family_id == family_id)
586            .cloned()
587            .collect())
588    }
589
590    async fn delete_family(&self, family_id: &str) -> Result<usize> {
591        let mut tokens = self
592            .tokens
593            .write()
594            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
595        let mut index = self
596            .token_index
597            .write()
598            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
599
600        let to_delete: Vec<_> = tokens
601            .iter()
602            .filter(|(_, t)| t.family_id == family_id)
603            .map(|(id, t)| (id.clone(), t.token.clone()))
604            .collect();
605
606        let count = to_delete.len();
607        for (token_id, token) in to_delete {
608            tokens.remove(&token_id);
609            index.remove(&token);
610        }
611
612        Ok(count)
613    }
614
615    async fn delete_by_user(&self, user_id: &str) -> Result<usize> {
616        let mut tokens = self
617            .tokens
618            .write()
619            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
620        let mut index = self
621            .token_index
622            .write()
623            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
624
625        let to_delete: Vec<_> = tokens
626            .iter()
627            .filter(|(_, t)| t.user_id == user_id)
628            .map(|(id, t)| (id.clone(), t.token.clone()))
629            .collect();
630
631        let count = to_delete.len();
632        for (token_id, token) in to_delete {
633            tokens.remove(&token_id);
634            index.remove(&token);
635        }
636
637        Ok(count)
638    }
639
640    async fn cleanup_expired(&self) -> Result<usize> {
641        let mut tokens = self
642            .tokens
643            .write()
644            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
645        let mut index = self
646            .token_index
647            .write()
648            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
649
650        let now = Utc::now().timestamp();
651        let to_delete: Vec<_> = tokens
652            .iter()
653            .filter(|(_, t)| t.expires_at < now)
654            .map(|(id, t)| (id.clone(), t.token.clone()))
655            .collect();
656
657        let count = to_delete.len();
658        for (token_id, token) in to_delete {
659            tokens.remove(&token_id);
660            index.remove(&token);
661        }
662
663        Ok(count)
664    }
665
666    async fn count(&self) -> Result<usize> {
667        let tokens = self
668            .tokens
669            .read()
670            .map_err(|_| Error::Storage(StorageError::OperationFailed("lock poisoned".into())))?;
671        Ok(tokens.len())
672    }
673}
674
675// ============================================================================
676// Token 使用结果
677// ============================================================================
678
679/// Token 使用结果
680#[derive(Debug, Clone)]
681pub struct TokenUseResult {
682    /// 新生成的 Token(如果启用了轮换)
683    pub new_token: Option<RefreshToken>,
684
685    /// 用户 ID
686    pub user_id: String,
687
688    /// Token 家族 ID
689    pub family_id: String,
690
691    /// 是否在宽限期内使用
692    pub was_in_grace_period: bool,
693}
694
695// ============================================================================
696// Refresh Token 管理器
697// ============================================================================
698
699/// Refresh Token 管理器
700///
701/// 提供 Refresh Token 的完整生命周期管理,包括生成、验证、轮换和撤销。
702///
703/// ## 示例
704///
705/// ```rust
706/// # tokio::runtime::Runtime::new().unwrap().block_on(async {
707/// use authrs::token::refresh::{RefreshTokenManager, RefreshConfig, GenerateOptions};
708///
709/// let manager = RefreshTokenManager::new(RefreshConfig::default());
710///
711/// // 生成 Token
712/// let token = manager.generate("user123").await.unwrap();
713///
714/// // 带元数据生成 Token
715/// let options = GenerateOptions::new()
716///     .with_device_info("iPhone 15")
717///     .with_ip_address("192.168.1.1");
718/// let token = manager
719///     .generate_with_options("user123", options)
720///     .await
721///     .unwrap();
722///
723/// // 使用 Token(会自动轮换)
724/// let result = manager.use_token(&token.token).await.unwrap();
725/// if let Some(new_token) = result.new_token {
726///     println!("使用新 Token: {}", new_token.token);
727/// }
728///
729/// // 撤销用户的所有 Token
730/// manager.revoke_all_for_user("user123").await.unwrap();
731/// # });
732/// ```
733pub struct RefreshTokenManager {
734    store: Arc<dyn RefreshTokenStore>,
735    config: RefreshConfig,
736}
737
738impl RefreshTokenManager {
739    /// 使用默认内存存储创建管理器
740    pub fn new(config: RefreshConfig) -> Self {
741        Self {
742            store: Arc::new(InMemoryRefreshTokenStore::new()),
743            config,
744        }
745    }
746
747    /// 使用自定义存储创建管理器
748    pub fn with_store(config: RefreshConfig, store: Arc<dyn RefreshTokenStore>) -> Self {
749        Self { store, config }
750    }
751
752    /// 生成新的 Refresh Token
753    ///
754    /// # 参数
755    ///
756    /// * `user_id` - 用户 ID
757    ///
758    /// # 返回
759    ///
760    /// 返回生成的 Token
761    pub async fn generate(&self, user_id: impl Into<String>) -> Result<RefreshToken> {
762        let user_id = user_id.into();
763        self.enforce_max_families(&user_id).await?;
764
765        let family_id = generate_random_hex(16)?;
766        let token = RefreshToken::new(&user_id, family_id, self.config.expiration)?;
767        self.store.save(&token).await?;
768
769        Ok(token)
770    }
771
772    /// 使用选项生成 Refresh Token
773    ///
774    /// 允许设置设备信息、IP 地址和初始元数据。
775    pub async fn generate_with_options(
776        &self,
777        user_id: impl Into<String>,
778        options: GenerateOptions,
779    ) -> Result<RefreshToken> {
780        let user_id = user_id.into();
781        self.enforce_max_families(&user_id).await?;
782
783        let family_id = options
784            .family_id
785            .unwrap_or_else(|| generate_random_hex(16).unwrap_or_default());
786        let mut token = RefreshToken::new(&user_id, family_id, self.config.expiration)?;
787
788        token.device_info = options.device_info;
789        token.ip_address = options.ip_address;
790
791        if let Some(metadata) = options.metadata {
792            token.metadata = metadata;
793        }
794
795        self.store.save(&token).await?;
796        Ok(token)
797    }
798
799    /// 使用 Refresh Token
800    ///
801    /// 如果启用了 Token 轮换,会生成新的 Token 并使旧 Token 失效。
802    /// 如果检测到重用攻击(已使用的 Token 被再次使用),会撤销整个 Token 家族。
803    ///
804    /// # 参数
805    ///
806    /// * `token` - Token 值
807    ///
808    /// # 返回
809    ///
810    /// 返回使用结果,包含新 Token(如果启用轮换)
811    pub async fn use_token(&self, token: &str) -> Result<TokenUseResult> {
812        let mut stored_token = self
813            .store
814            .get_by_token(token)
815            .await?
816            .ok_or_else(|| Error::Token(TokenError::InvalidFormat("token not found".into())))?;
817
818        // 检查是否过期
819        if stored_token.is_expired() {
820            self.store.delete(&stored_token.token_id).await?;
821            return Err(Error::Token(TokenError::Expired));
822        }
823
824        // 检查重用攻击
825        if stored_token.used {
826            if self.config.reuse_detection {
827                // 检查是否在宽限期内
828                let grace_period_secs = self.config.grace_period.num_seconds();
829                let used_at = stored_token.used_at.unwrap_or(0);
830                let now = Utc::now().timestamp();
831
832                // 如果宽限期为 0,或者已超过宽限期,则触发重用检测
833                if grace_period_secs == 0 || now > used_at + grace_period_secs {
834                    // 撤销整个家族
835                    self.store.delete_family(&stored_token.family_id).await?;
836                    return Err(Error::Token(TokenError::InvalidFormat(
837                        "token reuse detected, family revoked".into(),
838                    )));
839                }
840
841                // 在宽限期内,允许使用
842                return Ok(TokenUseResult {
843                    new_token: None,
844                    user_id: stored_token.user_id.clone(),
845                    family_id: stored_token.family_id.clone(),
846                    was_in_grace_period: true,
847                });
848            } else {
849                return Err(Error::Token(TokenError::InvalidFormat(
850                    "token already used".into(),
851                )));
852            }
853        }
854
855        // Token 轮换
856        let new_token = if self.config.rotation_enabled {
857            // 创建新 Token
858            let mut new = RefreshToken::new(
859                &stored_token.user_id,
860                stored_token.family_id.clone(),
861                self.config.expiration,
862            )?;
863
864            // 继承设备信息
865            new.device_info = stored_token.device_info.clone();
866            new.ip_address = stored_token.ip_address.clone();
867            new.metadata = stored_token.metadata.clone();
868
869            // 标记旧 Token 为已使用
870            stored_token.mark_as_used(Some(new.token_id.clone()));
871            self.store.update(&stored_token).await?;
872
873            // 保存新 Token
874            self.store.save(&new).await?;
875
876            // 清理家族中的旧 Token
877            self.enforce_max_tokens_per_family(&stored_token.family_id)
878                .await?;
879
880            Some(new)
881        } else {
882            // 不轮换,只标记为已使用
883            stored_token.mark_as_used(None);
884            self.store.update(&stored_token).await?;
885            None
886        };
887
888        Ok(TokenUseResult {
889            new_token,
890            user_id: stored_token.user_id,
891            family_id: stored_token.family_id,
892            was_in_grace_period: false,
893        })
894    }
895
896    /// 验证 Token
897    ///
898    /// 只检查 Token 是否有效,不会使用或轮换 Token。
899    pub async fn validate(&self, token: &str) -> Result<RefreshToken> {
900        let stored_token = self
901            .store
902            .get_by_token(token)
903            .await?
904            .ok_or_else(|| Error::Token(TokenError::InvalidFormat("token not found".into())))?;
905
906        if stored_token.is_expired() {
907            return Err(Error::Token(TokenError::Expired));
908        }
909
910        if stored_token.used && self.config.reuse_detection {
911            return Err(Error::Token(TokenError::InvalidFormat(
912                "token already used".into(),
913            )));
914        }
915
916        Ok(stored_token)
917    }
918
919    /// 撤销 Token
920    pub async fn revoke(&self, token: &str) -> Result<()> {
921        if let Some(stored) = self.store.get_by_token(token).await? {
922            self.store.delete(&stored.token_id).await?;
923        }
924        Ok(())
925    }
926
927    /// 撤销 Token 家族
928    pub async fn revoke_family(&self, family_id: &str) -> Result<usize> {
929        self.store.delete_family(family_id).await
930    }
931
932    /// 撤销用户的所有 Token
933    pub async fn revoke_all_for_user(&self, user_id: &str) -> Result<usize> {
934        self.store.delete_by_user(user_id).await
935    }
936
937    /// 获取用户的所有 Token
938    pub async fn get_user_tokens(&self, user_id: &str) -> Result<Vec<RefreshToken>> {
939        self.store.get_by_user(user_id).await
940    }
941
942    /// 获取 Token 家族的所有 Token
943    pub async fn get_family_tokens(&self, family_id: &str) -> Result<Vec<RefreshToken>> {
944        self.store.get_by_family(family_id).await
945    }
946
947    /// 清理过期的 Token
948    pub async fn cleanup(&self) -> Result<usize> {
949        self.store.cleanup_expired().await
950    }
951
952    /// 获取 Token 总数
953    pub async fn count(&self) -> Result<usize> {
954        self.store.count().await
955    }
956
957    /// 获取配置
958    pub fn config(&self) -> &RefreshConfig {
959        &self.config
960    }
961
962    // ========================================================================
963    // 内部方法
964    // ========================================================================
965
966    /// 强制执行单用户最大 Token 家族数限制
967    async fn enforce_max_families(&self, user_id: &str) -> Result<()> {
968        if self.config.max_families_per_user == 0 {
969            return Ok(());
970        }
971
972        let tokens = self.store.get_by_user(user_id).await?;
973
974        // 收集所有家族 ID 及其创建时间
975        let mut families: HashMap<String, i64> = HashMap::new();
976        for token in tokens {
977            families
978                .entry(token.family_id.clone())
979                .or_insert(token.created_at);
980        }
981
982        // 如果超出限制,删除最旧的家族
983        // 使用 (created_at, family_id) 作为排序键,确保在时间戳相同时有确定性行为
984        if families.len() >= self.config.max_families_per_user
985            && let Some((oldest_family, _)) =
986                families
987                    .iter()
988                    .min_by(|(id_a, created_a), (id_b, created_b)| {
989                        created_a.cmp(created_b).then_with(|| id_a.cmp(id_b))
990                    })
991        {
992            self.store.delete_family(oldest_family).await?;
993        }
994
995        Ok(())
996    }
997
998    /// 强制执行单家族最大 Token 数限制
999    async fn enforce_max_tokens_per_family(&self, family_id: &str) -> Result<()> {
1000        if self.config.max_tokens_per_family == 0 {
1001            return Ok(());
1002        }
1003
1004        let mut tokens = self.store.get_by_family(family_id).await?;
1005
1006        // 按创建时间排序
1007        tokens.sort_by_key(|t| t.created_at);
1008
1009        // 删除超出限制的旧 Token
1010        while tokens.len() > self.config.max_tokens_per_family {
1011            if let Some(oldest) = tokens.first() {
1012                self.store.delete(&oldest.token_id).await?;
1013                tokens.remove(0);
1014            }
1015        }
1016
1017        Ok(())
1018    }
1019}
1020
1021// ============================================================================
1022// 生成选项
1023// ============================================================================
1024
1025/// 生成 Refresh Token 的选项
1026#[derive(Debug, Clone, Default)]
1027pub struct GenerateOptions {
1028    /// 设备信息
1029    pub device_info: Option<String>,
1030
1031    /// IP 地址
1032    pub ip_address: Option<String>,
1033
1034    /// 初始元数据
1035    pub metadata: Option<serde_json::Value>,
1036
1037    /// 指定家族 ID(用于在已有家族中生成新 Token)
1038    pub family_id: Option<String>,
1039}
1040
1041impl GenerateOptions {
1042    /// 创建新的选项
1043    pub fn new() -> Self {
1044        Self::default()
1045    }
1046
1047    /// 设置设备信息
1048    pub fn with_device_info(mut self, info: impl Into<String>) -> Self {
1049        self.device_info = Some(info.into());
1050        self
1051    }
1052
1053    /// 设置 IP 地址
1054    pub fn with_ip_address(mut self, ip: impl Into<String>) -> Self {
1055        self.ip_address = Some(ip.into());
1056        self
1057    }
1058
1059    /// 设置初始元数据
1060    pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
1061        self.metadata = Some(metadata);
1062        self
1063    }
1064
1065    /// 设置初始元数据(从可序列化类型)
1066    pub fn with_metadata_from<T: Serialize>(mut self, data: T) -> Self {
1067        self.metadata = serde_json::to_value(data).ok();
1068        self
1069    }
1070
1071    /// 设置家族 ID
1072    pub fn with_family_id(mut self, family_id: impl Into<String>) -> Self {
1073        self.family_id = Some(family_id.into());
1074        self
1075    }
1076}
1077
1078// ============================================================================
1079// 测试
1080// ============================================================================
1081
1082#[cfg(test)]
1083mod tests {
1084    use super::*;
1085
1086    #[test]
1087    fn test_refresh_token_creation() {
1088        let token =
1089            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1090
1091        assert!(!token.token.is_empty());
1092        assert!(!token.token_id.is_empty());
1093        assert_eq!(token.user_id, "user123");
1094        assert_eq!(token.family_id, "family1");
1095        assert!(!token.used);
1096        assert!(!token.is_expired());
1097        assert!(token.is_valid());
1098    }
1099
1100    #[test]
1101    fn test_refresh_token_expiration() {
1102        let mut token =
1103            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1104        assert!(!token.is_expired());
1105
1106        // 手动设置过期
1107        token.expires_at = Utc::now().timestamp() - 1;
1108        assert!(token.is_expired());
1109        assert!(!token.is_valid());
1110    }
1111
1112    #[test]
1113    fn test_refresh_token_mark_as_used() {
1114        let mut token =
1115            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1116        assert!(token.is_valid());
1117
1118        token.mark_as_used(Some("new_token_id".to_string()));
1119
1120        assert!(token.used);
1121        assert!(token.used_at.is_some());
1122        assert_eq!(token.replaced_by, Some("new_token_id".to_string()));
1123        assert!(!token.is_valid());
1124    }
1125
1126    #[test]
1127    fn test_refresh_token_metadata() {
1128        let mut token =
1129            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1130
1131        // 设置元数据
1132        token.set_metadata("device", "iPhone");
1133        token.set_metadata("count", 42);
1134        token.set_metadata("tags", vec!["a", "b"]);
1135
1136        // 获取元数据
1137        let device: Option<String> = token.get_metadata("device");
1138        assert_eq!(device, Some("iPhone".to_string()));
1139
1140        let count: Option<i32> = token.get_metadata("count");
1141        assert_eq!(count, Some(42));
1142
1143        // 检查存在性
1144        assert!(token.has_metadata("device"));
1145        assert!(!token.has_metadata("nonexistent"));
1146
1147        // 删除元数据
1148        token.remove_metadata("device");
1149        assert!(!token.has_metadata("device"));
1150    }
1151
1152    #[tokio::test]
1153    async fn test_manager_generate() {
1154        let manager = RefreshTokenManager::new(RefreshConfig::default());
1155        let token = manager.generate("user123").await.unwrap();
1156
1157        assert_eq!(token.user_id, "user123");
1158        assert!(!token.token.is_empty());
1159    }
1160
1161    #[tokio::test]
1162    async fn test_manager_use_token_with_rotation() {
1163        let config = RefreshConfig::default().with_rotation(true);
1164        let manager = RefreshTokenManager::new(config);
1165
1166        let token = manager.generate("user123").await.unwrap();
1167        let result = manager.use_token(&token.token).await.unwrap();
1168
1169        assert!(result.new_token.is_some());
1170        assert_eq!(result.user_id, "user123");
1171
1172        // 原 token 应该失效
1173        assert!(manager.validate(&token.token).await.is_err());
1174    }
1175
1176    #[tokio::test]
1177    async fn test_manager_use_token_without_rotation() {
1178        let config = RefreshConfig::default().with_rotation(false);
1179        let manager = RefreshTokenManager::new(config);
1180
1181        let token = manager.generate("user123").await.unwrap();
1182        let result = manager.use_token(&token.token).await.unwrap();
1183
1184        assert!(result.new_token.is_none());
1185    }
1186
1187    #[tokio::test]
1188    async fn test_manager_reuse_detection() {
1189        let config = RefreshConfig::default()
1190            .with_rotation(true)
1191            .with_reuse_detection(true)
1192            .with_grace_period(Duration::seconds(0));
1193        let manager = RefreshTokenManager::new(config);
1194
1195        let token = manager.generate("user123").await.unwrap();
1196        let token_str = token.token.clone();
1197        let family_id = token.family_id.clone();
1198
1199        // 第一次使用
1200        let result = manager.use_token(&token_str).await.unwrap();
1201        assert!(result.new_token.is_some());
1202        let new_token = result.new_token.unwrap();
1203
1204        // 尝试重用旧 token(应该触发重用检测)
1205        let reuse_result = manager.use_token(&token_str).await;
1206        assert!(reuse_result.is_err());
1207
1208        // 整个家族应该被撤销
1209        assert!(manager.validate(&new_token.token).await.is_err());
1210        assert_eq!(
1211            manager.get_family_tokens(&family_id).await.unwrap().len(),
1212            0
1213        );
1214    }
1215
1216    #[tokio::test]
1217    async fn test_manager_revoke() {
1218        let manager = RefreshTokenManager::new(RefreshConfig::default());
1219        let token = manager.generate("user123").await.unwrap();
1220
1221        manager.revoke(&token.token).await.unwrap();
1222        assert!(manager.validate(&token.token).await.is_err());
1223    }
1224
1225    #[tokio::test]
1226    async fn test_manager_revoke_all_for_user() {
1227        let config = RefreshConfig::default().with_max_families_per_user(0);
1228        let manager = RefreshTokenManager::new(config);
1229
1230        manager.generate("user123").await.unwrap();
1231        manager.generate("user123").await.unwrap();
1232        manager.generate("user456").await.unwrap();
1233
1234        let count = manager.revoke_all_for_user("user123").await.unwrap();
1235        assert_eq!(count, 2);
1236
1237        assert_eq!(manager.get_user_tokens("user123").await.unwrap().len(), 0);
1238        assert_eq!(manager.get_user_tokens("user456").await.unwrap().len(), 1);
1239    }
1240
1241    #[tokio::test]
1242    async fn test_manager_max_families() {
1243        let config = RefreshConfig::default().with_max_families_per_user(2);
1244        let manager = RefreshTokenManager::new(config);
1245
1246        let t1 = manager.generate("user123").await.unwrap();
1247        let t2 = manager.generate("user123").await.unwrap();
1248        let t3 = manager.generate("user123").await.unwrap();
1249
1250        // 生成第三个 token 时,应该删除一个旧的家族
1251        // 最终应该只有 2 个家族存在
1252        let tokens = manager.get_user_tokens("user123").await.unwrap();
1253        let families: std::collections::HashSet<_> =
1254            tokens.iter().map(|t| t.family_id.clone()).collect();
1255        assert_eq!(families.len(), 2);
1256
1257        // 验证只有 2 个 token 是有效的(第三个 token 和另一个存活的 token)
1258        let mut valid_count = 0;
1259        for t in [&t1.token, &t2.token, &t3.token] {
1260            if manager.validate(t).await.is_ok() {
1261                valid_count += 1;
1262            }
1263        }
1264        assert_eq!(valid_count, 2);
1265
1266        // 第三个 token 应该始终有效(刚创建的)
1267        assert!(manager.validate(&t3.token).await.is_ok());
1268    }
1269
1270    #[tokio::test]
1271    async fn test_manager_validate() {
1272        let manager = RefreshTokenManager::new(RefreshConfig::default());
1273        let token = manager.generate("user123").await.unwrap();
1274
1275        let validated = manager.validate(&token.token).await.unwrap();
1276        assert_eq!(validated.user_id, "user123");
1277    }
1278
1279    #[tokio::test]
1280    async fn test_manager_cleanup() {
1281        let manager = RefreshTokenManager::new(RefreshConfig::default());
1282
1283        // 创建一个已过期的 token
1284        let mut token =
1285            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1286        token.expires_at = Utc::now().timestamp() - 100;
1287        manager.store.save(&token).await.unwrap();
1288
1289        // 创建一个有效的 token
1290        manager.generate("user456").await.unwrap();
1291
1292        let cleaned = manager.cleanup().await.unwrap();
1293        assert_eq!(cleaned, 1);
1294        assert_eq!(manager.count().await.unwrap(), 1);
1295    }
1296
1297    #[test]
1298    fn test_config_presets() {
1299        let high_security = RefreshConfig::high_security();
1300        assert!(high_security.rotation_enabled);
1301        assert!(high_security.reuse_detection);
1302        assert_eq!(high_security.expiration.num_days(), 7);
1303
1304        let relaxed = RefreshConfig::relaxed();
1305        assert!(!relaxed.rotation_enabled);
1306        assert!(!relaxed.reuse_detection);
1307    }
1308
1309    #[tokio::test]
1310    async fn test_generate_with_options() {
1311        let manager = RefreshTokenManager::new(RefreshConfig::default());
1312
1313        let options = GenerateOptions::new()
1314            .with_device_info("iPhone 15")
1315            .with_ip_address("192.168.1.1");
1316
1317        let token = manager
1318            .generate_with_options("user123", options)
1319            .await
1320            .unwrap();
1321
1322        assert_eq!(token.device_info, Some("iPhone 15".to_string()));
1323        assert_eq!(token.ip_address, Some("192.168.1.1".to_string()));
1324    }
1325
1326    #[test]
1327    fn test_token_time_to_live() {
1328        let token =
1329            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1330        let ttl = token.time_to_live();
1331        assert!(ttl > 3500 && ttl <= 3600);
1332    }
1333
1334    #[tokio::test]
1335    async fn test_in_memory_store() {
1336        let store = InMemoryRefreshTokenStore::new();
1337
1338        let token =
1339            RefreshToken::new("user123", "family1".to_string(), Duration::hours(1)).unwrap();
1340        store.save(&token).await.unwrap();
1341
1342        let retrieved = store.get_by_token(&token.token).await.unwrap();
1343        assert!(retrieved.is_some());
1344        assert_eq!(retrieved.unwrap().user_id, "user123");
1345
1346        let by_id = store.get_by_id(&token.token_id).await.unwrap();
1347        assert!(by_id.is_some());
1348
1349        store.delete(&token.token_id).await.unwrap();
1350        assert!(store.get_by_token(&token.token).await.unwrap().is_none());
1351    }
1352
1353    #[tokio::test]
1354    async fn test_token_rotation_inherits_metadata() {
1355        let manager = RefreshTokenManager::new(RefreshConfig::default().with_rotation(true));
1356
1357        let mut token = manager.generate("user123").await.unwrap();
1358        token.set_metadata("custom_key", "custom_value");
1359        token.device_info = Some("TestDevice".to_string());
1360        manager.store.update(&token).await.unwrap();
1361
1362        let result = manager.use_token(&token.token).await.unwrap();
1363        let new_token = result.new_token.unwrap();
1364
1365        // 新 token 应该继承元数据和设备信息
1366        assert_eq!(new_token.device_info, Some("TestDevice".to_string()));
1367        let value: Option<String> = new_token.get_metadata("custom_key");
1368        assert_eq!(value, Some("custom_value".to_string()));
1369    }
1370}