Skip to main content

cool_core/middleware/
mod.rs

1//! 中间件模块
2//!
3//! 对应 TypeScript 版本的 `middleware/`
4
5mod authority;
6mod exception;
7mod log;
8
9pub use authority::*;
10pub use exception::*;
11pub use log::*;
12
13use crate::error::CoolError;
14use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
15use salvo::prelude::*;
16use serde::{Deserialize, Serialize};
17
18/// JWT Claims
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct JwtClaims {
21    /// 用户 ID
22    pub user_id: i64,
23    /// 用户名
24    pub username: Option<String>,
25    /// 角色 ID 列表
26    pub role_ids: Vec<i64>,
27    /// 是否是管理员
28    pub is_admin: bool,
29    /// 租户 ID
30    pub tenant_id: Option<i64>,
31    /// 过期时间
32    pub exp: i64,
33    /// 签发时间
34    pub iat: i64,
35}
36
37impl JwtClaims {
38    /// 创建新的 Claims
39    pub fn new(
40        user_id: i64,
41        username: Option<String>,
42        role_ids: Vec<i64>,
43        is_admin: bool,
44        tenant_id: Option<i64>,
45        expire_secs: u64,
46    ) -> Self {
47        let now = chrono::Utc::now().timestamp();
48        Self {
49            user_id,
50            username,
51            role_ids,
52            is_admin,
53            tenant_id,
54            exp: now + expire_secs as i64,
55            iat: now,
56        }
57    }
58
59    /// 生成 token
60    pub fn generate_token(&self, secret: &str) -> Result<String, CoolError> {
61        encode(
62            &Header::default(),
63            &self,
64            &EncodingKey::from_secret(secret.as_bytes()),
65        )
66        .map_err(CoolError::from)
67    }
68
69    /// 验证并解析 token
70    pub fn verify_token(token: &str, secret: &str) -> Result<Self, CoolError> {
71        let token_data = decode::<Self>(
72            token,
73            &DecodingKey::from_secret(secret.as_bytes()),
74            &Validation::default(),
75        )
76        .map_err(CoolError::from)?;
77
78        Ok(token_data.claims)
79    }
80}
81
82/// Admin 用户信息(存储在 Depot 中)
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct AdminInfo {
85    /// 用户 ID
86    pub user_id: i64,
87    /// 用户名
88    pub username: Option<String>,
89    /// 角色 ID 列表
90    pub role_ids: Vec<i64>,
91    /// 是否是超级管理员
92    pub is_admin: bool,
93    /// 租户 ID
94    pub tenant_id: Option<i64>,
95}
96
97impl From<JwtClaims> for AdminInfo {
98    fn from(claims: JwtClaims) -> Self {
99        Self {
100            user_id: claims.user_id,
101            username: claims.username,
102            role_ids: claims.role_ids,
103            is_admin: claims.is_admin,
104            tenant_id: claims.tenant_id,
105        }
106    }
107}
108
109/// 从 Depot 获取 Admin 信息的扩展方法
110pub trait DepotExt {
111    fn admin(&self) -> Option<&AdminInfo>;
112    fn set_admin(&mut self, admin: AdminInfo);
113}
114
115impl DepotExt for Depot {
116    fn admin(&self) -> Option<&AdminInfo> {
117        self.get::<AdminInfo>("admin").ok()
118    }
119
120    fn set_admin(&mut self, admin: AdminInfo) {
121        self.insert("admin", admin);
122    }
123}
124
125/// App 用户信息(存储在 Depot 中)
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct AppUserInfo {
128    /// 用户 ID
129    pub id: i64,
130    /// 用户名
131    pub username: Option<String>,
132    /// 手机号
133    pub phone: Option<String>,
134    /// 租户 ID
135    pub tenant_id: Option<i64>,
136}
137
138/// 从 Depot 获取 App 用户信息的扩展方法
139pub trait DepotAppUserExt {
140    fn app_user(&self) -> Option<&AppUserInfo>;
141    fn set_app_user(&mut self, user: AppUserInfo);
142}
143
144impl DepotAppUserExt for Depot {
145    fn app_user(&self) -> Option<&AppUserInfo> {
146        self.get::<AppUserInfo>("app_user").ok()
147    }
148
149    fn set_app_user(&mut self, user: AppUserInfo) {
150        self.insert("app_user", user);
151    }
152}