feat: Add axum-extra dependency and refactor auth middleware for improved token handling

This commit is contained in:
MythEclipse
2025-08-14 23:16:41 +07:00
parent 10dc869eaf
commit 01e20baa45
3 changed files with 27 additions and 41 deletions
Generated
+1
View File
@@ -2314,6 +2314,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"axum-extra",
"axum-test",
"chrono",
"futures",
+1
View File
@@ -9,6 +9,7 @@ imphnen-libs.workspace = true
imphnen-utils.workspace = true
imphnen-entities.workspace = true
axum.workspace = true
axum-extra.workspace = true
serde.workspace = true
serde_json.workspace = true
utoipa.workspace = true
+25 -41
View File
@@ -2,52 +2,36 @@ use axum::{
Extension, extract::Request, http::StatusCode, middleware::Next,
response::Response,
};
use imphnen_iam::{UsersDetailQueryDto, UsersRepository};
use imphnen_libs::AppState;
use imphnen_utils::{common_response, extract_email, extract_email_async};
use imphnen_libs::{AppState, jsonwebtoken::decode_access_token};
use imphnen_utils::common_response;
use axum_extra::headers::{authorization::Bearer, Authorization, HeaderMapExt};
use std::convert::Infallible;
pub async fn auth_middleware(
Extension(state): Extension<AppState>,
Extension(_state): Extension<AppState>, // state is currently unused in this middleware
mut req: Request,
next: Next,
) -> Result<Response, Infallible> {
let headers = req.headers();
// Try synchronous email extraction first (for internal JWT tokens)
let email = match extract_email(headers) {
Some(email) => email,
None => {
// If sync extraction fails, try async (for Google tokens)
match extract_email_async(headers).await {
Some(email) => email,
None => {
return Ok(common_response(
StatusCode::UNAUTHORIZED,
"Invalid or expired token",
));
}
}
}
};
let repository = UsersRepository::new(&state);
let user: Option<UsersDetailQueryDto> =
match repository.query_user_by_email(email).await {
Ok(user) => Some(user),
Err(err) => {
return Ok(common_response(
StatusCode::INTERNAL_SERVER_ERROR,
&err.to_string(),
));
}
};
if user.is_none() {
return Ok(common_response(
StatusCode::UNAUTHORIZED,
"Unauthorized user",
));
}
req.extensions_mut().insert(user.unwrap());
let auth_header = match req
.headers()
.typed_get::<Authorization<Bearer>>() {
Some(header) => header,
None => return Ok(common_response(
StatusCode::UNAUTHORIZED,
"Invalid or missing authorization token",
)),
};
let token = auth_header.token();
let claims = match decode_access_token(token) {
Ok(token_data) => token_data.claims,
Err(_) => return Ok(common_response(
StatusCode::UNAUTHORIZED,
"Invalid or expired token",
)),
};
req.extensions_mut().insert(claims);
Ok(next.run(req).await)
}