完善request context中间件,错误信息使用i18n处理
This commit is contained in:
parent
461edb0f25
commit
0d8802b495
3
i18n.csv
3
i18n.csv
@ -11,4 +11,5 @@ ValidateAccountPasswordRequired,password is required,密码不能为空
|
|||||||
ValidateAccountIdTokenRequired,ID Token is required,用户ID Token不能为空
|
ValidateAccountIdTokenRequired,ID Token is required,用户ID Token不能为空
|
||||||
ValidateAccountLangTagRequired,lang tag is required,用户语言标识不能为空
|
ValidateAccountLangTagRequired,lang tag is required,用户语言标识不能为空
|
||||||
ValidatePageablePageRequired,invalid page number,页码无效
|
ValidatePageablePageRequired,invalid page number,页码无效
|
||||||
ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效
|
ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效
|
||||||
|
BadRequest,bad request,无效请求
|
|
@ -2,7 +2,9 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
|
|||||||
|
|
||||||
#[derive(Debug, EnumIter, EnumString, Display, PartialEq, AsRefStr)]
|
#[derive(Debug, EnumIter, EnumString, Display, PartialEq, AsRefStr)]
|
||||||
pub enum MessageId {
|
pub enum MessageId {
|
||||||
|
BadRequest,
|
||||||
ServerInternalError,
|
ServerInternalError,
|
||||||
|
|
||||||
Hello,
|
Hello,
|
||||||
AccountDisabled,
|
AccountDisabled,
|
||||||
AccountNoPermission,
|
AccountNoPermission,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response}};
|
use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response}};
|
||||||
use http::{header, StatusCode};
|
use http::{header, StatusCode};
|
||||||
|
use i18n::{message, message_ids::MessageId};
|
||||||
use jsonwebtoken::{decode, DecodingKey, Validation};
|
use jsonwebtoken::{decode, DecodingKey, Validation};
|
||||||
|
|
||||||
use crate::{cache::account_cache::LOGIN_CACHE, config, context::{Context, WhiteContext}, token::Claims};
|
use crate::{cache::account_cache::LOGIN_CACHE, config, context::{Context, WhiteContext}, token::Claims};
|
||||||
@ -11,6 +12,7 @@ const WHITE_LIST: &[(&str, &str)] = &[
|
|||||||
|
|
||||||
/// 认证中间件,包括网络请求白名单、token验证、登录缓存
|
/// 认证中间件,包括网络请求白名单、token验证、登录缓存
|
||||||
pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
||||||
|
let mut language = String::from("zh-CN");
|
||||||
// 获取请求的url和method,然后判断是否在白名单中,如果在白名单中,则直接返回next(req),否则继续执行下面的代码
|
// 获取请求的url和method,然后判断是否在白名单中,如果在白名单中,则直接返回next(req),否则继续执行下面的代码
|
||||||
let method = req.method().clone().to_string();
|
let method = req.method().clone().to_string();
|
||||||
let uri = req.uri().path_and_query().unwrap().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() {
|
}).is_some() {
|
||||||
// 解析语言
|
// 解析语言
|
||||||
let language_header = req.headers().get(header::ACCEPT_LANGUAGE);
|
let language_header = req.headers().get(header::ACCEPT_LANGUAGE);
|
||||||
let language = match language_header {
|
language = match language_header {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let value_str: Vec<&str> = value.to_str().unwrap_or("zh-CN").split(',').collect();
|
let value_str: Vec<&str> = value.to_str().unwrap_or("zh-CN").split(',').collect();
|
||||||
if value_str.is_empty() {
|
if value_str.is_empty() {
|
||||||
String::from("zh-CN")
|
language
|
||||||
} else {
|
} else {
|
||||||
String::from(value_str[0])
|
String::from(value_str[0])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => String::from("zh-CN"),
|
None => language,
|
||||||
};
|
};
|
||||||
req.extensions_mut().insert(WhiteContext { lang_tag: language });
|
req.extensions_mut().insert(WhiteContext { lang_tag: language });
|
||||||
return next.run(req).await;
|
return next.run(req).await;
|
||||||
@ -40,11 +42,15 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
|||||||
Some(header_value) => {
|
Some(header_value) => {
|
||||||
let parts: Vec<&str> = header_value.to_str().unwrap_or("").split_whitespace().collect();
|
let parts: Vec<&str> = header_value.to_str().unwrap_or("").split_whitespace().collect();
|
||||||
if parts.len() != 2 || parts[0] != "Bearer" {
|
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]
|
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();
|
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;
|
let account = LOGIN_CACHE.get(&decoded.claims.sub).await;
|
||||||
if account.is_none() {
|
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();
|
let account = account.unwrap();
|
||||||
// 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在)
|
// 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在)
|
||||||
@ -69,6 +76,9 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
|||||||
});
|
});
|
||||||
next.run(req).await
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ use library::{context::{Context, WhiteContext}, model::{response::ResResult, val
|
|||||||
use crate::service;
|
use crate::service;
|
||||||
|
|
||||||
/// post: /account/google
|
/// post: /account/google
|
||||||
|
///
|
||||||
/// google账号登录
|
/// google账号登录
|
||||||
pub async fn authenticate_google(
|
pub async fn authenticate_google(
|
||||||
Extension(context): Extension<WhiteContext>,
|
Extension(context): Extension<WhiteContext>,
|
||||||
@ -15,6 +16,7 @@ pub async fn authenticate_google(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// post: /account/sys
|
/// post: /account/sys
|
||||||
|
///
|
||||||
/// 账号密码登录
|
/// 账号密码登录
|
||||||
pub async fn authenticate_with_password(
|
pub async fn authenticate_with_password(
|
||||||
Extension(context): Extension<WhiteContext>,
|
Extension(context): Extension<WhiteContext>,
|
||||||
@ -25,6 +27,7 @@ pub async fn authenticate_with_password(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// post: /account/refresh-token
|
/// post: /account/refresh-token
|
||||||
|
///
|
||||||
/// 刷新token
|
/// 刷新token
|
||||||
pub async fn refresh_token(
|
pub async fn refresh_token(
|
||||||
Extension(context): Extension<Context>,
|
Extension(context): Extension<Context>,
|
||||||
|
@ -10,6 +10,7 @@ use library::model::validator;
|
|||||||
use crate::service;
|
use crate::service;
|
||||||
|
|
||||||
/// post: /feedback
|
/// post: /feedback
|
||||||
|
///
|
||||||
/// 添加反馈信息
|
/// 添加反馈信息
|
||||||
pub async fn add_feedback(
|
pub async fn add_feedback(
|
||||||
Extension(context): Extension<Context>,
|
Extension(context): Extension<Context>,
|
||||||
@ -20,6 +21,7 @@ pub async fn add_feedback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// get: /feedback
|
/// get: /feedback
|
||||||
|
///
|
||||||
/// 获取反馈信息列表
|
/// 获取反馈信息列表
|
||||||
pub async fn get_feedback_list_by_page(
|
pub async fn get_feedback_list_by_page(
|
||||||
Extension(context): Extension<Context>,
|
Extension(context): Extension<Context>,
|
||||||
|
Loading…
Reference in New Issue
Block a user