diff --git a/api/src/controller/account.rs b/api/src/controller/account.rs index dda8455..bf3ccd6 100644 --- a/api/src/controller/account.rs +++ b/api/src/controller/account.rs @@ -1,6 +1,6 @@ use axum::{Extension, Json}; use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}}; -use library::{cache::account_cache::CacheAccount, res::{response::{ ResData, ResResult}, validator}}; +use library::{context::Context, res::{response::{ ResData, ResResult}, validator}}; pub async fn authenticate_google( Json(req): Json @@ -17,10 +17,10 @@ pub async fn authenticate_with_password( } pub async fn refresh_token( - Extension(account): Extension, + Extension(context): Extension, Json(refresh_token): Json ) -> ResResult> { - tracing::debug!("刷新token, {:?}", account); + tracing::debug!("刷新token, {:?}", context); validator::validate_params(&refresh_token, "")?; - service::account::refresh_token(account, refresh_token.token).await + service::account::refresh_token(context, refresh_token.token).await } diff --git a/api/src/router.rs b/api/src/router.rs index 459b754..2af7486 100644 --- a/api/src/router.rs +++ b/api/src/router.rs @@ -27,7 +27,7 @@ pub(crate) fn init() -> Router { .get(controller::feedback::get_feedback_list_by_page), ) .layer(axum::middleware::from_fn( - library::middleware::req_token::authenticate_access_token, + library::middleware::req_ctx::authenticate_ctx, )); Router::new() diff --git a/library/src/context.rs b/library/src/context.rs new file mode 100644 index 0000000..ba609ee --- /dev/null +++ b/library/src/context.rs @@ -0,0 +1,23 @@ +use domain::entities::account::Account; + +#[derive(Debug, Clone)] + +pub struct Context { + pub account: Account, + pub local: String, + pub token: String, +} + +impl Context { + pub fn get_account(&self) -> &Account { + &self.account + } + + pub fn get_token(&self) -> &String { + &self.token + } + + pub fn get_local(&self) -> &String { + &self.local + } +} \ No newline at end of file diff --git a/library/src/lib.rs b/library/src/lib.rs index c1bed03..3ecd36f 100644 --- a/library/src/lib.rs +++ b/library/src/lib.rs @@ -5,4 +5,5 @@ pub mod res; pub mod middleware; pub mod token; pub mod social; -pub mod cache; \ No newline at end of file +pub mod cache; +pub mod context; \ No newline at end of file diff --git a/library/src/middleware/mod.rs b/library/src/middleware/mod.rs index 857c556..c879d3d 100644 --- a/library/src/middleware/mod.rs +++ b/library/src/middleware/mod.rs @@ -1,4 +1,4 @@ pub mod req_id; pub mod req_log; pub mod cors; -pub mod req_token; \ No newline at end of file +pub mod req_ctx; \ No newline at end of file diff --git a/library/src/middleware/req_token.rs b/library/src/middleware/req_ctx.rs similarity index 74% rename from library/src/middleware/req_token.rs rename to library/src/middleware/req_ctx.rs index fecac49..2574f05 100644 --- a/library/src/middleware/req_token.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, token::Claims}; +use crate::{cache::account_cache::LOGIN_CACHE, config, context::Context, token::Claims}; const WHITE_LIST: &[(&str, &str)] = &[ ("GET", "/api/v1/users/:id"), @@ -11,7 +11,7 @@ const WHITE_LIST: &[(&str, &str)] = &[ ("POST", "/account/sys"), ]; -pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response { +pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response { // 获取请求的url和method,然后判断是否在白名单中,如果在白名单中,则直接返回next(req),否则继续执行下面的代码 let method = req.method().clone().to_string(); let uri = req.uri().path_and_query().unwrap().to_string(); @@ -21,6 +21,7 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response return next.run(req).await; } + // 解析token let auth_header = req.headers().get(header::AUTHORIZATION); let token = match auth_header { Some(header_value) => { @@ -33,6 +34,20 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response None => return (StatusCode::UNAUTHORIZED, "Missing authorization header".to_string()).into_response(), }; + // 解析语言 + 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(); + if value_str.is_empty() { + String::from("zh-CN") + } else { + String::from(value_str[1]) + } + }, + None => String::from("zh-CN"), + }; + let validation = Validation::default(); match decode::(token, &DecodingKey::from_secret(config!().jwt.token_secret.as_bytes()), &validation) { Ok(decoded) => { @@ -41,13 +56,14 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response if account.is_none() { return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(); } + let account = account.unwrap(); // 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在) // let account = account.unwrap(); // if account.token != token { // return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(); // } // 将Claims附加到请求扩展中,以便后续处理使用 - req.extensions_mut().insert(account.unwrap()); + req.extensions_mut().insert(Context { account: account.account, local: language, token: account.token }); next.run(req).await }, Err(_) => (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(), diff --git a/library/src/res/validator.rs b/library/src/res/validator.rs index abcd6a6..838cf25 100644 --- a/library/src/res/validator.rs +++ b/library/src/res/validator.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use validator::Validate; use super::response::{ResData, ResErr, ResResult}; diff --git a/service/src/account.rs b/service/src/account.rs index b07751b..bba06ce 100644 --- a/service/src/account.rs +++ b/service/src/account.rs @@ -3,6 +3,7 @@ use domain::dto::account::AuthenticateGooleAccountReq; use domain::entities::account::Account; use domain::vo::account::{LoginAccount, RefreshTokenResult}; use library::cache::account_cache::{CacheAccount, LOGIN_CACHE}; +use library::context::Context; use library::res::response::ResErr::ErrPerm; use library::res::response::{ResData, ResErr, ResResult}; use library::social::google::GOOGLE_SOCIAL; @@ -74,10 +75,10 @@ pub async fn authenticate_google( } pub async fn refresh_token( - cache_account: CacheAccount, + context: Context, refresh_token: String, ) -> ResResult> { - let account = cache_account.account; + let account = context.account; if token::verify_refresh_token(&refresh_token).is_err() { return Err(ResErr::params("refresh_token无效"));