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 = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"axum-test",
|
||||
"chrono",
|
||||
"futures",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user