修改context,移除WhiteContext
This commit is contained in:
parent
7024a4f19d
commit
d002c68fc2
@ -4,30 +4,28 @@ use domain::entities::account::Account;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Context {
|
||||
pub account: Arc<Account>,
|
||||
pub token: Arc<String>,
|
||||
pub account: Option<Arc<Account>>,
|
||||
pub token: Option<Arc<String>>,
|
||||
pub lang_tag: Arc<String>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn get_account(&self) -> &Account {
|
||||
&self.account
|
||||
pub fn get_account(&self) -> Option<Arc<Account>> {
|
||||
if let Some(account) = &self.account {
|
||||
return Some(account.clone());
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_token(&self) -> &String {
|
||||
&self.token
|
||||
pub fn get_token(&self) -> Option<Arc<String>> {
|
||||
if let Some(token) = &self.token {
|
||||
return Some(token.clone());
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
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}, model::response::ResErr, token::Claims, utils::request_util};
|
||||
use crate::{cache::account_cache::LOGIN_CACHE, config, context::Context, model::response::ResErr, token::Claims, utils::request_util};
|
||||
|
||||
const WHITE_LIST: &[(&str, &str)] = &[
|
||||
("POST", "/account/sys"),
|
||||
@ -12,9 +14,6 @@ const WHITE_LIST: &[(&str, &str)] = &[
|
||||
|
||||
/// 认证中间件,包括网络请求白名单、token验证、登录缓存
|
||||
pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
||||
// 解析语言
|
||||
let language = request_util::get_lang_tag(req.headers());
|
||||
req.extensions_mut().insert(WhiteContext { lang_tag: language.clone() });
|
||||
// 获取请求的url和method,然后判断是否在白名单中,如果在白名单中,则直接返回next(req),否则继续执行下面的代码
|
||||
let method = req.method().clone().to_string();
|
||||
let mut uri = req.uri().path_and_query().unwrap().to_string();
|
||||
@ -23,6 +22,9 @@ 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 = request_util::get_lang_tag(req.headers());
|
||||
req.extensions_mut().insert(Context { lang_tag: Arc::new(language.clone()), account: None, token: None });
|
||||
return next.run(req).await;
|
||||
}
|
||||
|
||||
@ -33,12 +35,16 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
||||
let parts: Vec<&str> = header_value.to_str().unwrap_or("").split_whitespace().collect();
|
||||
if parts.len() != 2 || parts[0] != "Bearer" {
|
||||
tracing::error!("无效的 authorization 请求头参数");
|
||||
// 解析语言
|
||||
let language = request_util::get_lang_tag(req.headers());
|
||||
return ResErr::params(message!(&language, MessageId::BadRequest)).into_response();
|
||||
}
|
||||
parts[1]
|
||||
},
|
||||
None => {
|
||||
tracing::error!("缺少 authorization 请求头参数");
|
||||
// 解析语言
|
||||
let language = request_util::get_lang_tag(req.headers());
|
||||
return ResErr::auth(message!(&language, MessageId::BadRequest)).into_response()
|
||||
},
|
||||
};
|
||||
@ -50,6 +56,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() {
|
||||
tracing::error!("无效的 token");
|
||||
// 解析语言
|
||||
let language = request_util::get_lang_tag(req.headers());
|
||||
return ResErr::auth(message!(&language, MessageId::BadRequest)).into_response();
|
||||
}
|
||||
let account = account.unwrap();
|
||||
@ -58,16 +66,20 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
|
||||
// if account.token != token {
|
||||
// return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
|
||||
// }
|
||||
let language = account.account.clone().lang_tag.clone();
|
||||
// 将Claims附加到请求扩展中,以便后续处理使用
|
||||
req.extensions_mut().insert(
|
||||
Context {
|
||||
account: account.account.clone(),
|
||||
token: account.token.clone()
|
||||
account: Some(account.account.clone()),
|
||||
token: Some(account.token.clone()),
|
||||
lang_tag: Arc::new(language)
|
||||
});
|
||||
next.run(req).await
|
||||
},
|
||||
Err(_) => {
|
||||
tracing::error!("无效的 token");
|
||||
// 解析语言
|
||||
let language = request_util::get_lang_tag(req.headers());
|
||||
return ResErr::auth(message!(&language, MessageId::BadRequest)).into_response();
|
||||
}
|
||||
}
|
||||
|
@ -19,21 +19,19 @@ where
|
||||
type Rejection = ResErr;
|
||||
|
||||
async fn from_request(req: http::Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
|
||||
// let context = req.extensions().get().unwrap();
|
||||
|
||||
let (parts, body) = req.into_parts();
|
||||
let header = &parts.headers;
|
||||
let query = Query::<T>::from_request(Request::from_parts(parts.clone(), body), state).await;
|
||||
let lang_tag = request_util::get_lang_tag(header);
|
||||
|
||||
if let Ok(Query(data)) = query {
|
||||
match data.validate() {
|
||||
match super::validator::validate_params(&data, &lang_tag) {
|
||||
Ok(_) => Ok(QueryValidator(data)),
|
||||
Err(_) => {
|
||||
let lang_tag = request_util::get_lang_tag(header);
|
||||
let err = Err(ResErr::params(message!(&lang_tag, MessageId::InvalidParams)));
|
||||
err
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
} else {
|
||||
let lang_tag = request_util::get_lang_tag(header);
|
||||
let err = Err(ResErr::params(message!(&lang_tag, MessageId::InvalidParams)));
|
||||
err
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use axum::extract::Request;
|
||||
use http::{header, HeaderMap, HeaderValue};
|
||||
|
||||
/// 获取请求的语言
|
||||
|
@ -1,6 +1,6 @@
|
||||
use axum::{Extension, Json};
|
||||
use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}};
|
||||
use library::{context::{Context, WhiteContext}, model::{response::ResResult, validator}};
|
||||
use library::{context::Context, model::{response::ResResult, validator}};
|
||||
|
||||
use crate::service;
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::service;
|
||||
///
|
||||
/// google账号登录
|
||||
pub async fn authenticate_google(
|
||||
Extension(context): Extension<WhiteContext>,
|
||||
Extension(context): Extension<Context>,
|
||||
Json(req): Json<AuthenticateGooleAccountReq>
|
||||
) -> ResResult<LoginAccount> {
|
||||
validator::validate_params(&req, context.get_lang_tag())?;
|
||||
@ -19,7 +19,7 @@ pub async fn authenticate_google(
|
||||
///
|
||||
/// 账号密码登录
|
||||
pub async fn authenticate_with_password(
|
||||
Extension(context): Extension<WhiteContext>,
|
||||
Extension(context): Extension<Context>,
|
||||
Json(req): Json<AuthenticateWithPassword>
|
||||
) -> ResResult<LoginAccount> {
|
||||
validator::validate_params(&req, context.get_lang_tag())?;
|
||||
|
@ -7,7 +7,7 @@ use domain::vo::account::{LoginAccount, RefreshTokenResult};
|
||||
use i18n::message;
|
||||
use i18n::message_ids::MessageId;
|
||||
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
|
||||
use library::context::{Context, WhiteContext};
|
||||
use library::context::Context;
|
||||
use library::model::response::ResErr::ErrPerm;
|
||||
use library::model::response::{ResErr, ResResult};
|
||||
use library::social::google::GOOGLE_SOCIAL;
|
||||
@ -15,7 +15,7 @@ use library::token::{generate_refresh_token, generate_token};
|
||||
use library::{db, token};
|
||||
|
||||
pub async fn authenticate_google(
|
||||
context: WhiteContext,
|
||||
context: Context,
|
||||
req: AuthenticateGooleAccountReq,
|
||||
) -> ResResult<LoginAccount> {
|
||||
let verify_result = GOOGLE_SOCIAL
|
||||
@ -100,11 +100,12 @@ pub async fn refresh_token(
|
||||
context: Context,
|
||||
refresh_token: String,
|
||||
) -> ResResult<RefreshTokenResult> {
|
||||
let account = context.account.clone();
|
||||
let lang = context.get_lang_tag();
|
||||
let account = context.get_account().unwrap();
|
||||
|
||||
if token::verify_refresh_token(&refresh_token).is_err() {
|
||||
return Err(ResErr::params(message!(
|
||||
context.get_lang_tag(),
|
||||
lang,
|
||||
MessageId::InvalidToken
|
||||
)));
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub async fn get_feedback_list_by_page(
|
||||
page: i64,
|
||||
page_size: i64,
|
||||
) -> ResResult<FeedbackPageable> {
|
||||
if !context.account.role.is_admin() {
|
||||
if !context.account.unwrap().role.is_admin() {
|
||||
tracing::error!("非管理员用户,无法获取反馈信息列表");
|
||||
return Ok(FeedbackPageable::empty(page, page_size));
|
||||
}
|
||||
@ -41,7 +41,7 @@ async fn get_feedback_count() -> i64 {
|
||||
|
||||
/// 添加反馈信息
|
||||
pub async fn add_feedback(context: Context, req: FeedbackAdd) -> ResResult<()> {
|
||||
let account = context.account;
|
||||
let account = context.account.unwrap();
|
||||
let mut transaction = db!().begin().await?;
|
||||
match Feedback::add_feedback(
|
||||
&mut Feedback {
|
||||
|
@ -11,12 +11,12 @@ use i18n::{
|
||||
message_ids::MessageId,
|
||||
};
|
||||
use library::{
|
||||
cache::account_cache::{CacheAccount, LOGIN_CACHE}, context::WhiteContext, db, model::response::{ResErr, ResResult}, token::{generate_refresh_token, generate_token}
|
||||
cache::account_cache::{CacheAccount, LOGIN_CACHE}, context::Context, db, model::response::{ResErr, ResResult}, token::{generate_refresh_token, generate_token}
|
||||
};
|
||||
|
||||
/// 登录, 使用账号和密码
|
||||
pub async fn authenticate_with_password(
|
||||
context: WhiteContext,
|
||||
context: Context,
|
||||
req: AuthenticateWithPassword,
|
||||
) -> ResResult<LoginAccount> {
|
||||
let account =
|
||||
|
Loading…
Reference in New Issue
Block a user