Skip to main content

server_common/
jwt.rs

1use chrono::{Duration, Utc};
2use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation, decode, encode};
3use serde::{Deserialize, Serialize};
4use server_config::{jwt::JwtConfig, uri::IgnoreUri};
5
6use crate::error::auth::AuthError;
7
8// 定义 JWT Claims
9#[derive(Debug, Serialize, Deserialize, Clone)]
10pub struct Claims {
11    pub sub: String, // 用户ID
12    pub exp: i64,    // 过期时间
13    pub iat: i64,    // 签发时间
14    pub data: Option<String>,
15}
16
17// Token 生成和验证
18pub struct JwtService {
19    config: JwtConfig,
20}
21
22impl JwtService {
23    pub fn new(mut config: JwtConfig) -> Self {
24        if let Some(data) = &mut config.ignore_uris {
25            JwtService::methods_to_uppercase(data);
26        }
27        print!("{:?}", &config);
28        Self { config }
29    }
30
31    // 生成 Token
32    pub fn generate_token(
33        &self,
34        user_info: &str,
35        data: Option<String>,
36    ) -> Result<String, jsonwebtoken::errors::Error> {
37        let now = Utc::now();
38        let exp = now + Duration::hours(self.config.expiration_hours);
39
40        let claims = Claims {
41            sub: user_info.to_string(),
42            exp: exp.timestamp(),
43            iat: now.timestamp(),
44            data,
45        };
46
47        encode(
48            &Header::default(),
49            &claims,
50            &EncodingKey::from_secret(self.config.secret.as_ref()),
51        )
52    }
53
54    // 验证 Token
55    pub fn verify_token(&self, token: &str) -> Result<Claims, AuthError> {
56        let token_data = decode::<Claims>(
57            token,
58            &DecodingKey::from_secret(self.config.secret.as_ref()),
59            &Validation::new(Algorithm::HS256),
60        )
61        .map_err(|_| AuthError::InvalidToken)?;
62
63        // 检查是否过期
64        let now = Utc::now().timestamp();
65        if token_data.claims.exp < now {
66            return Err(AuthError::ExpiredToken);
67        }
68
69        Ok(token_data.claims)
70    }
71
72    // 获取加密钥匙
73    pub fn get_secret(&self) -> String {
74        self.config.secret.clone()
75    }
76
77    // 获取过期时间戳
78    pub fn get_expiration(&self) -> i64 {
79        self.config.expiration_hours
80    }
81
82    // 获取忽略uri信息
83    pub fn is_ignore_uri(&self, uri: &str, method: &str) -> bool {
84        if let Some(data) = &self.config.ignore_uris {
85            for item in data.iter() {
86                // 判断是否在跳过验证路径中
87                if uri.starts_with(&item.path) && item.method.contains(&method.to_uppercase()) {
88                    return true;
89                }
90            }
91            false
92        } else {
93            false
94        }
95    }
96
97    // 将请求方法转大写
98    pub fn methods_to_uppercase(data: &mut [IgnoreUri]) {
99        for item in data.iter_mut() {
100            for method in item.method.iter_mut() {
101                *method = method.to_uppercase();
102            }
103        }
104    }
105}