diff --git a/api/src/controller/account.rs b/api/src/controller/account.rs index fb59bd4..b48b03c 100644 --- a/api/src/controller/account.rs +++ b/api/src/controller/account.rs @@ -1,19 +1,21 @@ use axum::{Extension, Json}; use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}}; -use library::{context::Context, res::{response::{ ResData, ResResult}, validator}}; +use library::{context::{Context, WhiteContext}, res::{response::{ ResData, ResResult}, validator}}; pub async fn authenticate_google( + Extension(context): Extension, Json(req): Json ) -> ResResult> { - validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?; - service::account::authenticate_google(req).await + validator::validate_params(&req, context.get_lang_tag())?; + service::account::authenticate_google(context, req).await } pub async fn authenticate_with_password( + Extension(context): Extension, Json(req): Json ) -> ResResult> { - validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?; - service::sys_account::authenticate_with_password(req).await + validator::validate_params(&req, context.get_lang_tag())?; + service::sys_account::authenticate_with_password(context, req).await } pub async fn refresh_token( diff --git a/domain/src/dto/account.rs b/domain/src/dto/account.rs index e60aa59..b3719bd 100644 --- a/domain/src/dto/account.rs +++ b/domain/src/dto/account.rs @@ -7,16 +7,12 @@ pub struct AuthenticateWithPassword { pub username: Option, #[validate(required(message = "VALIDATE_ACCOUNT_PASSWORD_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_PASSWORD_REQUIRED"))] pub password: Option, - #[validate(required(message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"))] - pub lang_tag: Option, } #[derive(Debug, Validate, Deserialize, Serialize)] pub struct AuthenticateGooleAccountReq { #[validate(required(message = "VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED"))] pub id_token: Option, - #[validate(required(message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"))] - pub lang_tag: Option, } #[derive(Debug, Validate, Deserialize, Serialize)] diff --git a/i18n/src/en_us.rs b/i18n/src/en_us.rs index dbd5f8c..63bb3de 100644 --- a/i18n/src/en_us.rs +++ b/i18n/src/en_us.rs @@ -6,7 +6,7 @@ use crate::message_ids::{ ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN, VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, VALIDATE_ACCOUNT_NAME_REQUIRED, VALIDATE_ACCOUNT_PASSWORD_REQUIRED, VALIDATE_FEEDBACK_CONTENT_REQUIRED }; -pub const LANGUAGE_ID: &str = "en_US"; +pub const LANGUAGE_ID: &str = "en-US"; lazy_static! { pub static ref MESSAGE: HashMap<&'static str, &'static str> = { diff --git a/i18n/src/zh_cn.rs b/i18n/src/zh_cn.rs index 9214d95..823e99a 100644 --- a/i18n/src/zh_cn.rs +++ b/i18n/src/zh_cn.rs @@ -6,7 +6,7 @@ use crate::message_ids::{ ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN, VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, VALIDATE_ACCOUNT_NAME_REQUIRED, VALIDATE_ACCOUNT_PASSWORD_REQUIRED, VALIDATE_FEEDBACK_CONTENT_REQUIRED }; -pub const LANGUAGE_ID: &str = "zh_CN"; +pub const LANGUAGE_ID: &str = "zh-CN"; lazy_static! { pub static ref MESSAGE: HashMap<&'static str, &'static str> = { diff --git a/library/src/context.rs b/library/src/context.rs index da956df..ccf58f5 100644 --- a/library/src/context.rs +++ b/library/src/context.rs @@ -18,7 +18,18 @@ impl Context { &self.token } - pub fn get_lang_id(&self) -> &String { + pub fn get_lang_tag(&self) -> &String { &self.account.lang_tag } +} + +#[derive(Debug, Clone)] +pub struct WhiteContext { + pub lang_tag: String, +} + +impl WhiteContext { + pub fn get_lang_tag(&self) -> &String { + &self.lang_tag + } } \ No newline at end of file diff --git a/library/src/middleware/req_ctx.rs b/library/src/middleware/req_ctx.rs index 214222d..2762ddb 100644 --- a/library/src/middleware/req_ctx.rs +++ b/library/src/middleware/req_ctx.rs @@ -2,7 +2,7 @@ use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response use http::{header, StatusCode}; use jsonwebtoken::{decode, DecodingKey, Validation}; -use crate::{cache::account_cache::LOGIN_CACHE, config, context::Context, token::Claims}; +use crate::{cache::account_cache::LOGIN_CACHE, config, context::{Context, WhiteContext}, token::Claims}; const WHITE_LIST: &[(&str, &str)] = &[ ("POST", "/account/sys"), @@ -16,6 +16,21 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response { if WHITE_LIST.into_iter().find(|item| { return item.0 == method && item.1 == uri; }).is_some() { + // 解析语言 + let language_header = req.headers().get(header::ACCEPT_LANGUAGE); + let language = match language_header { + Some(value) => { + let value_str: Vec<&str> = value.to_str().unwrap_or("zh-CN").split(',').collect(); + tracing::info!("language: {:?}", value_str); + if value_str.is_empty() { + String::from("zh-CN") + } else { + String::from(value_str[0]) + } + }, + None => String::from("zh-CN"), + }; + req.extensions_mut().insert(WhiteContext { lang_tag: language }); return next.run(req).await; } diff --git a/service/src/account.rs b/service/src/account.rs index b59ec7c..f0708f9 100644 --- a/service/src/account.rs +++ b/service/src/account.rs @@ -7,7 +7,7 @@ use domain::vo::account::{LoginAccount, RefreshTokenResult}; use i18n::message; use i18n::message_ids::{ACCOUNT_DISABLED, INVALID_TOKEN}; use library::cache::account_cache::{CacheAccount, LOGIN_CACHE}; -use library::context::Context; +use library::context::{Context, WhiteContext}; use library::res::response::ResErr::ErrPerm; use library::res::response::{ResData, ResErr, ResResult}; use library::social::google::GOOGLE_SOCIAL; @@ -15,9 +15,9 @@ use library::token::{generate_refresh_token, generate_token}; use library::{db, token}; pub async fn authenticate_google( + context: WhiteContext, req: AuthenticateGooleAccountReq, ) -> ResResult> { - let lang_tag = req.lang_tag.unwrap(); let verify_result = GOOGLE_SOCIAL .verify_id_token(&req.id_token.unwrap()) .await @@ -47,7 +47,7 @@ pub async fn authenticate_google( tracing::info!("账户已存在, {:?}", account); if account.disable_time > Utc::now() { tracing::error!("账户已禁用"); - return Err(ResErr::system(message!(&lang_tag, ACCOUNT_DISABLED))); + return Err(ResErr::system(message!(context.get_lang_tag(), ACCOUNT_DISABLED))); } account } @@ -86,7 +86,7 @@ pub async fn refresh_token( let account = context.account.clone(); if token::verify_refresh_token(&refresh_token).is_err() { - return Err(ResErr::params(message!(context.get_lang_id(), INVALID_TOKEN))); + return Err(ResErr::params(message!(context.get_lang_tag(), INVALID_TOKEN))); } let refresh_token = RefreshTokenResult { diff --git a/service/src/sys_account.rs b/service/src/sys_account.rs index 40aa894..8ce9da8 100644 --- a/service/src/sys_account.rs +++ b/service/src/sys_account.rs @@ -11,22 +11,19 @@ use i18n::{ message_ids::{ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, INCORRECT_USERNAME_OR_PASSWORD}, }; use library::{ - cache::account_cache::{CacheAccount, LOGIN_CACHE}, - db, - res::response::{ResData, ResErr, ResResult}, - token::{generate_refresh_token, generate_token}, + cache::account_cache::{CacheAccount, LOGIN_CACHE}, context::WhiteContext, db, res::response::{ResData, ResErr, ResResult}, token::{generate_refresh_token, generate_token} }; pub async fn authenticate_with_password( + context: WhiteContext, req: AuthenticateWithPassword, ) -> ResResult> { - let lang_tag = req.lang_tag.unwrap(); let account = Account::find_with_password(req.username.unwrap(), req.password.unwrap(), db!()).await?; if account.is_none() { tracing::info!("登录用户失败,用户查询为空"); return Err(ResErr::params(message!( - &lang_tag, + context.get_lang_tag(), INCORRECT_USERNAME_OR_PASSWORD ))); } @@ -34,14 +31,14 @@ pub async fn authenticate_with_password( if account.disable_time > Utc::now() { tracing::error!("账户已禁用"); return Err(ResErr::auth(message!( - &lang_tag, + context.get_lang_tag(), ACCOUNT_DISABLED ))); } if !account.role.is_admin() { tracing::error!("账户不是管理员,无权限"); return Err(ResErr::perm(message!( - &lang_tag, + context.get_lang_tag(), ACCOUNT_NO_PERMISSION ))); }