完善request context中间件,错误信息使用i18n处理

This commit is contained in:
李运家 2024-09-27 18:52:32 +08:00
parent 461edb0f25
commit 0d8802b495
5 changed files with 26 additions and 8 deletions

View File

@ -12,3 +12,4 @@ ValidateAccountIdTokenRequired,ID Token is required,用户ID Token不能为空
ValidateAccountLangTagRequired,lang tag is required,用户语言标识不能为空
ValidatePageablePageRequired,invalid page number,页码无效
ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效
BadRequest,bad request,无效请求
1 id en-US zh-CN
12 ValidateAccountLangTagRequired lang tag is required 用户语言标识不能为空
13 ValidatePageablePageRequired invalid page number 页码无效
14 ValidatePageablePageSizeRequired invalid quantity per page 每页数量无效
15 BadRequest bad request 无效请求

View File

@ -2,7 +2,9 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
#[derive(Debug, EnumIter, EnumString, Display, PartialEq, AsRefStr)]
pub enum MessageId {
BadRequest,
ServerInternalError,
Hello,
AccountDisabled,
AccountNoPermission,

View File

@ -1,5 +1,6 @@
use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response}};
use http::{header, StatusCode};
use i18n::{message, message_ids::MessageId};
use jsonwebtoken::{decode, DecodingKey, Validation};
use crate::{cache::account_cache::LOGIN_CACHE, config, context::{Context, WhiteContext}, token::Claims};
@ -11,6 +12,7 @@ const WHITE_LIST: &[(&str, &str)] = &[
/// 认证中间件包括网络请求白名单、token验证、登录缓存
pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
let mut language = String::from("zh-CN");
// 获取请求的url和method然后判断是否在白名单中如果在白名单中则直接返回next(req),否则继续执行下面的代码
let method = req.method().clone().to_string();
let uri = req.uri().path_and_query().unwrap().to_string();
@ -19,16 +21,16 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
}).is_some() {
// 解析语言
let language_header = req.headers().get(header::ACCEPT_LANGUAGE);
let language = match language_header {
language = match language_header {
Some(value) => {
let value_str: Vec<&str> = value.to_str().unwrap_or("zh-CN").split(',').collect();
if value_str.is_empty() {
String::from("zh-CN")
language
} else {
String::from(value_str[0])
}
},
None => String::from("zh-CN"),
None => language,
};
req.extensions_mut().insert(WhiteContext { lang_tag: language });
return next.run(req).await;
@ -40,11 +42,15 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
Some(header_value) => {
let parts: Vec<&str> = header_value.to_str().unwrap_or("").split_whitespace().collect();
if parts.len() != 2 || parts[0] != "Bearer" {
return (StatusCode::BAD_REQUEST, "Invalid authorization header format".to_string()).into_response();
tracing::error!("无效的 authorization 请求头参数");
return (StatusCode::BAD_REQUEST, message!(&language, MessageId::BadRequest)).into_response();
}
parts[1]
},
None => return (StatusCode::UNAUTHORIZED, "Missing authorization header".to_string()).into_response(),
None => {
tracing::error!("缺少 authorization 请求头参数");
return (StatusCode::UNAUTHORIZED, message!(&language, MessageId::BadRequest)).into_response()
},
};
let validation = Validation::default();
@ -53,7 +59,8 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
// 从缓存中获取当前用户信息
let account = LOGIN_CACHE.get(&decoded.claims.sub).await;
if account.is_none() {
return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
tracing::error!("无效的 token");
return (StatusCode::UNAUTHORIZED, message!(&language, MessageId::BadRequest)).into_response();
}
let account = account.unwrap();
// 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在)
@ -69,6 +76,9 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
});
next.run(req).await
},
Err(_) => (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(),
Err(_) => {
tracing::error!("无效的 token");
return (StatusCode::UNAUTHORIZED, message!(&language, MessageId::BadRequest)).into_response();
}
}
}

View File

@ -5,6 +5,7 @@ use library::{context::{Context, WhiteContext}, model::{response::ResResult, val
use crate::service;
/// post: /account/google
///
/// google账号登录
pub async fn authenticate_google(
Extension(context): Extension<WhiteContext>,
@ -15,6 +16,7 @@ pub async fn authenticate_google(
}
/// post: /account/sys
///
/// 账号密码登录
pub async fn authenticate_with_password(
Extension(context): Extension<WhiteContext>,
@ -25,6 +27,7 @@ pub async fn authenticate_with_password(
}
/// post: /account/refresh-token
///
/// 刷新token
pub async fn refresh_token(
Extension(context): Extension<Context>,

View File

@ -10,6 +10,7 @@ use library::model::validator;
use crate::service;
/// post: /feedback
///
/// 添加反馈信息
pub async fn add_feedback(
Extension(context): Extension<Context>,
@ -20,6 +21,7 @@ pub async fn add_feedback(
}
/// get: /feedback
///
/// 获取反馈信息列表
pub async fn get_feedback_list_by_page(
Extension(context): Extension<Context>,