axum-with-seaorm/src/common/jwt/mod.rs

65 lines
1.9 KiB
Rust

use chrono::{Duration, Utc};
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation};
use jsonwebtoken::errors::ErrorKind;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use crate::APPLICATION_CONTEXT;
use crate::common::err::{AppError, AppErrorType};
use crate::common::Result;
use crate::config::app::AppConfig;
lazy_static! {
pub static ref JWT_SECRET: String = {
let app_cfg = APPLICATION_CONTEXT.get::<AppConfig>();
app_cfg.jwt_secret.clone()
};
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JwtClaims {
// 账号id
pub id: u32,
// 账号
pub email: String,
// 过期时间
pub exp: i64,
// 签名时间
pub iat: i64,
}
impl JwtClaims {
pub fn new(id: u32, email: String) -> Self {
let iat = Utc::now();
let exp = iat + Duration::hours(24);
Self {
id,
email,
exp: exp.timestamp(),
iat: iat.timestamp(),
}
}
pub fn sign(&self) -> Result<String> {
let encoding_key = EncodingKey::from_secret(JWT_SECRET.as_bytes());
jsonwebtoken::encode(&Header::default(), self, &encoding_key)
.map_err(AppError::from)
}
pub fn verify(token: &str) -> Result<JwtClaims> {
let decode_key = DecodingKey::from_secret(JWT_SECRET.as_bytes());
let validation = Validation::default();
match jsonwebtoken::decode::<JwtClaims>(token, &decode_key, &validation) {
Ok(c) => Ok(c.claims),
Err(e) => match e.kind() {
ErrorKind::InvalidToken => Err(AppError::from_msg("Token失效", AppErrorType::Authorization)),
ErrorKind::InvalidIssuer => Err(AppError::from_msg("InvalidIssuer", AppErrorType::Authorization)),
_ => Err(AppError::from_msg("InvalidToken other errors", AppErrorType::Authorization))
},
}
}
}