auth middleware + message history
This commit is contained in:
70
src/auth.rs
70
src/auth.rs
@@ -1,15 +1,22 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use axum::{extract::State, http::StatusCode};
|
||||
use axum::{
|
||||
extract::{Request, State},
|
||||
http::StatusCode,
|
||||
middleware::Next,
|
||||
response::Response,
|
||||
};
|
||||
use chrono::Utc;
|
||||
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{FromRow, Postgres};
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Claims {
|
||||
pub user_id: u32,
|
||||
pub user_id: i64,
|
||||
pub iat: usize,
|
||||
pub exp: usize,
|
||||
}
|
||||
@@ -29,7 +36,7 @@ pub static AUTH_PUBLIC_KEY: LazyLock<DecodingKey> = LazyLock::new(|| {
|
||||
});
|
||||
|
||||
impl Claims {
|
||||
pub fn new(user_id: u32) -> Self {
|
||||
pub fn new(user_id: i64) -> Self {
|
||||
let now = (Utc::now().timestamp_millis() / 1000) as usize;
|
||||
Self {
|
||||
user_id,
|
||||
@@ -40,16 +47,26 @@ impl Claims {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, FromRow)]
|
||||
pub struct User {
|
||||
id: i64,
|
||||
}
|
||||
|
||||
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);
|
||||
let Ok(user) = sqlx::query_as::<Postgres, User>("INSERT INTO users DEFAULT VALUES RETURNING *")
|
||||
.fetch_one(&state.pg_pool)
|
||||
.await
|
||||
else {
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
};
|
||||
|
||||
*next_client_id += 1;
|
||||
let claims = Claims::new(user.id);
|
||||
|
||||
encode(&Header::new(Algorithm::RS512), &claims, &AUTH_SECRET_KEY).map_err(|e| {
|
||||
dbg!(&e);
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
})
|
||||
let Ok(token) = encode(&Header::new(Algorithm::RS512), &claims, &AUTH_SECRET_KEY) else {
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
};
|
||||
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
pub fn verify_token(token: &str) -> Option<Claims> {
|
||||
@@ -57,9 +74,34 @@ pub fn verify_token(token: &str) -> Option<Claims> {
|
||||
|
||||
decode::<Claims>(token, key, &Validation::new(Algorithm::RS512))
|
||||
.map(|token_data| token_data.claims)
|
||||
.map_err(|e| {
|
||||
println!("{e:?}");
|
||||
e
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
const AUTH_HEADER_PREFIX: &'static str = "Bearer ";
|
||||
|
||||
pub async fn authentication_middleware(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<Response, StatusCode> {
|
||||
let Some(Ok(auth_header)) = request
|
||||
.headers()
|
||||
.get(axum::http::header::AUTHORIZATION)
|
||||
.map(|header| header.to_str())
|
||||
else {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
};
|
||||
|
||||
if auth_header.len() <= AUTH_HEADER_PREFIX.len() {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
let token = auth_header.split_at(AUTH_HEADER_PREFIX.len()).1;
|
||||
|
||||
let Some(claims) = verify_token(token) else {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
};
|
||||
|
||||
request.extensions_mut().insert(claims);
|
||||
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user