use anyhow;
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AccessToken {
pub user_id: u64, pub user_name: String, pub user_account: String, pub app_id: String, pub platform: String, pub is_admin: bool, pub is_super: bool, pub exp: u64,
}
impl AccessToken {
pub fn encode_token(
user_id: u64,
user_account: &String,
user_name: &String,
app_id: &String,
platform: &String,
is_admin: bool,
is_super: bool,
timeout_hour: u16,
secret: &str,
) -> anyhow::Result<String> {
let header = Header::new(Algorithm::HS512);
let my_claims = AccessToken {
user_id: user_id.clone(),
user_account: user_account.clone(),
user_name: user_name.clone(),
app_id: app_id.clone(),
platform: platform.clone(),
is_admin: is_admin,
is_super: is_super,
exp: (std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs()
+ 60 * 60 * (timeout_hour as u64)),
};
if let Ok(token) = encode(
&header,
&my_claims,
&EncodingKey::from_secret(secret.as_ref()),
) {
return anyhow::Ok(token);
} else {
return Err(anyhow::anyhow!("encode_token with error"));
}
}
pub fn decode_token(token: &String, secret: &str) -> anyhow::Result<Self> {
if let Ok(decode_data) = decode::<Self>(
&token,
&DecodingKey::from_secret(secret.as_ref()),
&Validation::new(Algorithm::HS512),
) {
return anyhow::Ok(decode_data.claims);
} else {
return Err(anyhow::anyhow!("decode_token with error"));
}
}
pub fn is_expired(&self) -> bool {
let cur_time = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
if self.exp < cur_time {
true
} else {
false
}
}
}
pub const ACCESS_TOKEN_TIME: u16 = 2 * 24;
pub const REFRESH_TOKEN_TIME: u16 = 7 * 24;
pub fn create_access_token(
user_id: u64,
user_account: &String,
user_name: &String,
app_id: &String,
platform: &String,
is_admin: bool,
is_super: bool,
secret: &str,
) -> anyhow::Result<String> {
AccessToken::encode_token(
user_id,
user_account,
user_name,
app_id,
platform,
is_admin,
is_super,
ACCESS_TOKEN_TIME,
secret,
)
}
pub fn create_refresh_token(
user_id: u64,
user_account: &String,
user_name: &String,
app_id: &String,
platform: &String,
is_admin: bool,
is_super: bool,
secret: &str,
) -> anyhow::Result<String> {
AccessToken::encode_token(
user_id,
user_account,
user_name,
app_id,
platform,
is_admin,
is_super,
REFRESH_TOKEN_TIME,
secret,
)
}