使用了jwt作为身份验证和分发
This commit is contained in:
81
src/auth.rs
Normal file
81
src/auth.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
use chrono::Utc;
|
||||
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
||||
|
||||
use crate::models::Claims;
|
||||
use actix_web::{
|
||||
Error, HttpMessage, body::MessageBody, dev::ServiceRequest, dev::ServiceResponse,
|
||||
middleware::Next,
|
||||
}; // 新增:用于包装中间件函数
|
||||
|
||||
// 中间件函数:泛型 B 约束为 MessageBody,返回 Result<ServiceResponse<B>, Error>
|
||||
pub async fn jwt_middleware<B: MessageBody>(
|
||||
req: ServiceRequest,
|
||||
next: Next<B>,
|
||||
) -> Result<ServiceResponse<B>, Error> {
|
||||
// (保持原有逻辑不变)
|
||||
let auth_header = req
|
||||
.headers()
|
||||
.get("Authorization")
|
||||
.ok_or_else(|| actix_web::error::ErrorUnauthorized("缺少Authorization头"))?
|
||||
.to_str()
|
||||
.map_err(|_| actix_web::error::ErrorUnauthorized("Authorization格式无效"))?;
|
||||
|
||||
let token = auth_header.strip_prefix("Bearer ").ok_or_else(|| {
|
||||
actix_web::error::ErrorUnauthorized("Authorization格式应为 Bearer <token>")
|
||||
})?;
|
||||
|
||||
let jwt_secret = std::env::var("JWT_SECRET")
|
||||
.map_err(|_| actix_web::error::ErrorInternalServerError("服务器未配置JWT密钥"))?;
|
||||
|
||||
let claims = verify_token(token, &jwt_secret)
|
||||
.map_err(|e| actix_web::error::ErrorUnauthorized(format!("无效的token: {}", e)))?;
|
||||
|
||||
req.extensions_mut().insert(claims);
|
||||
next.call(req).await
|
||||
}
|
||||
|
||||
// 生成JWT的函数
|
||||
pub fn generate_token(
|
||||
user_id: i32,
|
||||
openid: &str,
|
||||
user_type: i32,
|
||||
secret: &str,
|
||||
) -> Result<String, String> {
|
||||
// 设置过期时间:当前时间 + 24小时(86400秒)
|
||||
let now = Utc::now();
|
||||
let exp = (now + chrono::Duration::hours(24)).timestamp();
|
||||
let iat = now.timestamp();
|
||||
|
||||
// 构建Claims
|
||||
let claims = Claims {
|
||||
exp,
|
||||
iat,
|
||||
user_id,
|
||||
openid: openid.to_string(),
|
||||
user_type,
|
||||
};
|
||||
|
||||
// 生成token
|
||||
encode(
|
||||
&Header::new(Algorithm::HS256), // 使用HS256算法
|
||||
&claims,
|
||||
&EncodingKey::from_secret(secret.as_bytes()), // 签名密钥
|
||||
)
|
||||
.map_err(|e| format!("生成JWT失败: {}", e))
|
||||
}
|
||||
|
||||
// 验证并解析JWT的函数
|
||||
pub fn verify_token(token: &str, secret: &str) -> Result<Claims, String> {
|
||||
// 验证配置(指定算法,默认会检查exp等字段)
|
||||
let validation = Validation::new(Algorithm::HS256);
|
||||
|
||||
// 解析token
|
||||
let decoded = decode::<Claims>(
|
||||
token,
|
||||
&DecodingKey::from_secret(secret.as_bytes()), // 与签发时相同的密钥
|
||||
&validation,
|
||||
)
|
||||
.map_err(|e| format!("JWT验证失败: {}", e))?;
|
||||
|
||||
Ok(decoded.claims)
|
||||
}
|
||||
Reference in New Issue
Block a user