feat: check token via jwt
This commit is contained in:
1 parent
42b836d064
commit
bc980a3b84
7 files changed
+107
-11
No files matched your search
+54
@@ -0,0 +1,54 @@
|
||||
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
pub static SECRET: Lazy<String> =
|
||||
Lazy::new(|| env::var("RUSTDESK_API_JWT_KEY").unwrap_or_else(|_| "".to_string()));
|
||||
|
||||
// 定义一个结构体来表示 JWT 的 payload
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Claims {
|
||||
user_id: u32,
|
||||
exp: usize,
|
||||
}
|
||||
|
||||
pub fn generate_token(user_id: u32, exp: i64) -> Result<String, String> {
|
||||
println!("secret: {:}", SECRET.to_string());
|
||||
let claims = Claims {
|
||||
user_id,
|
||||
exp: (chrono::Utc::now() + chrono::Duration::seconds(exp)).timestamp() as usize,
|
||||
};
|
||||
|
||||
let token = encode(
|
||||
&Header::default(),
|
||||
&claims,
|
||||
&EncodingKey::from_secret(SECRET.as_ref()),
|
||||
);
|
||||
|
||||
match token {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
// 验证 JWT 的函数
|
||||
pub fn verify_token(token: &str) -> Result<Claims, String> {
|
||||
// 解码 JWT
|
||||
let validation = Validation::new(Algorithm::HS256);
|
||||
|
||||
let decoded = decode::<Claims>(
|
||||
&token,
|
||||
&DecodingKey::from_secret(SECRET.as_ref()),
|
||||
&validation,
|
||||
);
|
||||
match decoded {
|
||||
Ok(token_data) => {
|
||||
let now = chrono::Utc::now().timestamp() as usize;
|
||||
if token_data.claims.exp > now {
|
||||
Ok(token_data.claims)
|
||||
} else {
|
||||
Err("Token status invalid or expired".to_string())
|
||||
}
|
||||
}
|
||||
Err(_) => Err("Invalid token".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,4 @@ pub mod common;
|
||||
mod database;
|
||||
mod peer;
|
||||
mod version;
|
||||
pub mod jwt;
|
||||
@@ -46,6 +46,7 @@ use std::{
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
use crate::jwt;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Data {
|
||||
@@ -776,14 +777,28 @@ impl RendezvousServer {
|
||||
});
|
||||
return Ok((msg_out, None));
|
||||
}
|
||||
// Todo check token by jwt
|
||||
if ph.token.is_empty() && MUST_LOGIN.load(Ordering::SeqCst) {
|
||||
let mut msg_out = RendezvousMessage::new();
|
||||
msg_out.set_punch_hole_response(PunchHoleResponse {
|
||||
other_failure: String::from("Connection failed, please login first"),
|
||||
..Default::default()
|
||||
});
|
||||
return Ok((msg_out, None));
|
||||
// if secret is not empty check token by jwt
|
||||
if MUST_LOGIN.load(Ordering::SeqCst) {
|
||||
if ph.token.is_empty() {
|
||||
let mut msg_out = RendezvousMessage::new();
|
||||
msg_out.set_punch_hole_response(PunchHoleResponse {
|
||||
other_failure: String::from("Connection failed, please login!"),
|
||||
..Default::default()
|
||||
});
|
||||
return Ok((msg_out, None));
|
||||
} else if !jwt::SECRET.is_empty() {
|
||||
let token = ph.token;
|
||||
let token = jwt::verify_token(token.as_str());
|
||||
if token.is_err() {
|
||||
let mut msg_out = RendezvousMessage::new();
|
||||
msg_out.set_punch_hole_response(PunchHoleResponse {
|
||||
//提示重新登录
|
||||
other_failure: String::from("Token error, please log out and log back in!"),
|
||||
..Default::default()
|
||||
});
|
||||
return Ok((msg_out, None));
|
||||
}
|
||||
}
|
||||
}
|
||||
let id = ph.id;
|
||||
// punch hole request from A, relay to B,
|
||||
|
||||
Reference in new issue
Block a user