sa_token_core/token/
generator.rs1use uuid::Uuid;
9use crate::config::{TokenStyle, SaTokenConfig};
10use crate::token::TokenValue;
11use crate::token::jwt::{JwtManager, JwtClaims, JwtAlgorithm};
12
13pub struct TokenGenerator;
14
15impl TokenGenerator {
16 pub fn generate_with_login_id(config: &SaTokenConfig, login_id: &str) -> TokenValue {
23 match config.token_style {
24 TokenStyle::Uuid => Self::generate_uuid(),
25 TokenStyle::SimpleUuid => Self::generate_simple_uuid(),
26 TokenStyle::Random32 => Self::generate_random(32),
27 TokenStyle::Random64 => Self::generate_random(64),
28 TokenStyle::Random128 => Self::generate_random(128),
29 TokenStyle::Jwt => Self::generate_jwt(config, login_id),
30 TokenStyle::Hash => Self::generate_hash(login_id),
31 TokenStyle::Timestamp => Self::generate_timestamp(),
32 TokenStyle::Tik => Self::generate_tik(),
33 }
34 }
35
36 pub fn generate(config: &SaTokenConfig) -> TokenValue {
38 Self::generate_with_login_id(config, "")
39 }
40
41 pub fn generate_uuid() -> TokenValue {
43 TokenValue::new(Uuid::new_v4().to_string())
44 }
45
46 pub fn generate_simple_uuid() -> TokenValue {
48 TokenValue::new(Uuid::new_v4().simple().to_string())
49 }
50
51 pub fn generate_random(length: usize) -> TokenValue {
53 use sha2::{Sha256, Digest};
54 let uuid = Uuid::new_v4();
55 let random_bytes = uuid.as_bytes();
56 let hash = Sha256::digest(random_bytes);
57 let hex_string = hex::encode(hash);
58 TokenValue::new(hex_string[..length.min(hex_string.len())].to_string())
59 }
60
61 pub fn generate_jwt(config: &SaTokenConfig, login_id: &str) -> TokenValue {
68 let secret = config.jwt_secret_key.as_ref()
70 .expect("JWT secret key is required when using JWT token style");
71
72 let algorithm = config.jwt_algorithm.as_ref()
74 .and_then(|alg| Self::parse_jwt_algorithm(alg))
75 .unwrap_or(JwtAlgorithm::HS256);
76
77 let mut jwt_manager = JwtManager::with_algorithm(secret, algorithm);
79
80 if let Some(ref issuer) = config.jwt_issuer {
81 jwt_manager = jwt_manager.set_issuer(issuer);
82 }
83
84 if let Some(ref audience) = config.jwt_audience {
85 jwt_manager = jwt_manager.set_audience(audience);
86 }
87
88 let mut claims = JwtClaims::new(login_id);
90
91 if config.timeout > 0 {
93 claims.set_expiration(config.timeout);
94 }
95
96 match jwt_manager.generate(&claims) {
98 Ok(token) => TokenValue::new(token),
99 Err(e) => {
100 eprintln!("Failed to generate JWT token: {:?}", e);
101 Self::generate_uuid()
103 }
104 }
105 }
106
107 fn parse_jwt_algorithm(alg: &str) -> Option<JwtAlgorithm> {
109 match alg.to_uppercase().as_str() {
110 "HS256" => Some(JwtAlgorithm::HS256),
111 "HS384" => Some(JwtAlgorithm::HS384),
112 "HS512" => Some(JwtAlgorithm::HS512),
113 "RS256" => Some(JwtAlgorithm::RS256),
114 "RS384" => Some(JwtAlgorithm::RS384),
115 "RS512" => Some(JwtAlgorithm::RS512),
116 "ES256" => Some(JwtAlgorithm::ES256),
117 "ES384" => Some(JwtAlgorithm::ES384),
118 _ => None,
119 }
120 }
121
122 pub fn generate_hash(login_id: &str) -> TokenValue {
131 use sha2::{Sha256, Digest};
132 use chrono::Utc;
133
134 let timestamp = Utc::now().timestamp_millis();
135 let uuid = Uuid::new_v4();
136 let data = format!("{}{}{}", login_id, timestamp, uuid);
137
138 let mut hasher = Sha256::new();
139 hasher.update(data.as_bytes());
140 let result = hasher.finalize();
141 let hash = hex::encode(result);
142
143 TokenValue::new(hash)
144 }
145
146 pub fn generate_timestamp() -> TokenValue {
154 use chrono::Utc;
155 use sha2::{Sha256, Digest};
156
157 let timestamp = Utc::now().timestamp_millis();
158 let uuid = Uuid::new_v4();
159
160 let mut hasher = Sha256::new();
162 hasher.update(uuid.as_bytes());
163 let result = hasher.finalize();
164 let suffix = hex::encode(&result[..8]); TokenValue::new(format!("{}_{}", timestamp, suffix))
167 }
168
169 pub fn generate_tik() -> TokenValue {
180 use sha2::{Sha256, Digest};
181
182 const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
183 const TOKEN_LENGTH: usize = 8;
184
185 let uuid = Uuid::new_v4();
186 let mut hasher = Sha256::new();
187 hasher.update(uuid.as_bytes());
188 let hash = hasher.finalize();
189
190 let mut token = String::with_capacity(TOKEN_LENGTH);
191 for i in 0..TOKEN_LENGTH {
192 let idx = (hash[i] as usize) % CHARSET.len();
193 token.push(CHARSET[idx] as char);
194 }
195
196 TokenValue::new(token)
197 }
198}