json web tokens (auth)

This commit is contained in:
2025-06-08 19:48:27 +02:00
parent 016940a45c
commit 4f03cde9b5
7 changed files with 255 additions and 12 deletions

65
src/auth.rs Normal file
View File

@@ -0,0 +1,65 @@
use std::sync::LazyLock;
use axum::{extract::State, http::StatusCode};
use chrono::Utc;
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation, decode, encode};
use serde::{Deserialize, Serialize};
use crate::state::AppState;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Claims {
pub user_id: u32,
pub iat: usize,
pub exp: usize,
}
pub static AUTH_SECRET_KEY: LazyLock<EncodingKey> = LazyLock::new(|| {
let bytes = std::fs::read("./private_key.pem").unwrap();
let encoding_key = EncodingKey::from_rsa_pem(&bytes).unwrap();
encoding_key
});
pub static AUTH_PUBLIC_KEY: LazyLock<DecodingKey> = LazyLock::new(|| {
let bytes = std::fs::read("./public_key.pem").unwrap();
let decoding_key = DecodingKey::from_rsa_pem(&bytes).unwrap();
decoding_key
});
impl Claims {
pub fn new(user_id: u32) -> Self {
let now = (Utc::now().timestamp_millis() / 1000) as usize;
Self {
user_id,
iat: now,
// Should be about 1 year
exp: now + 31540000,
}
}
}
pub async fn get_auth_token(State(state): State<AppState>) -> Result<String, StatusCode> {
let mut next_client_id = state.next_client_id.lock().await;
let claims = Claims::new(*next_client_id);
*next_client_id += 1;
encode(&Header::new(Algorithm::RS512), &claims, &AUTH_SECRET_KEY).map_err(|e| {
dbg!(&e);
StatusCode::INTERNAL_SERVER_ERROR
})
}
pub fn verify_token(token: &str) -> Option<Claims> {
let key = &*AUTH_PUBLIC_KEY;
decode::<Claims>(token, key, &Validation::new(Algorithm::RS512))
.map(|token_data| token_data.claims)
.map_err(|e| {
println!("{e:?}");
e
})
.ok()
}