feat: Add axum-extra dependency and refactor auth middleware for improved token handling
This commit is contained in:
Generated
+1
@@ -2314,6 +2314,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
|
"axum-extra",
|
||||||
"axum-test",
|
"axum-test",
|
||||||
"chrono",
|
"chrono",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ imphnen-libs.workspace = true
|
|||||||
imphnen-utils.workspace = true
|
imphnen-utils.workspace = true
|
||||||
imphnen-entities.workspace = true
|
imphnen-entities.workspace = true
|
||||||
axum.workspace = true
|
axum.workspace = true
|
||||||
|
axum-extra.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
utoipa.workspace = true
|
utoipa.workspace = true
|
||||||
|
|||||||
@@ -2,52 +2,36 @@ use axum::{
|
|||||||
Extension, extract::Request, http::StatusCode, middleware::Next,
|
Extension, extract::Request, http::StatusCode, middleware::Next,
|
||||||
response::Response,
|
response::Response,
|
||||||
};
|
};
|
||||||
use imphnen_iam::{UsersDetailQueryDto, UsersRepository};
|
use imphnen_libs::{AppState, jsonwebtoken::decode_access_token};
|
||||||
use imphnen_libs::AppState;
|
use imphnen_utils::common_response;
|
||||||
use imphnen_utils::{common_response, extract_email, extract_email_async};
|
use axum_extra::headers::{authorization::Bearer, Authorization, HeaderMapExt};
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
pub async fn auth_middleware(
|
pub async fn auth_middleware(
|
||||||
Extension(state): Extension<AppState>,
|
Extension(_state): Extension<AppState>, // state is currently unused in this middleware
|
||||||
mut req: Request,
|
mut req: Request,
|
||||||
next: Next,
|
next: Next,
|
||||||
) -> Result<Response, Infallible> {
|
) -> Result<Response, Infallible> {
|
||||||
let headers = req.headers();
|
let auth_header = match req
|
||||||
|
.headers()
|
||||||
// Try synchronous email extraction first (for internal JWT tokens)
|
.typed_get::<Authorization<Bearer>>() {
|
||||||
let email = match extract_email(headers) {
|
Some(header) => header,
|
||||||
Some(email) => email,
|
None => return Ok(common_response(
|
||||||
None => {
|
StatusCode::UNAUTHORIZED,
|
||||||
// If sync extraction fails, try async (for Google tokens)
|
"Invalid or missing authorization token",
|
||||||
match extract_email_async(headers).await {
|
)),
|
||||||
Some(email) => email,
|
};
|
||||||
None => {
|
|
||||||
return Ok(common_response(
|
let token = auth_header.token();
|
||||||
StatusCode::UNAUTHORIZED,
|
|
||||||
"Invalid or expired 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",
|
||||||
};
|
)),
|
||||||
|
};
|
||||||
let repository = UsersRepository::new(&state);
|
|
||||||
let user: Option<UsersDetailQueryDto> =
|
req.extensions_mut().insert(claims);
|
||||||
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());
|
|
||||||
Ok(next.run(req).await)
|
Ok(next.run(req).await)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user