增加网络请求上下文
This commit is contained in:
parent
6572f48696
commit
a7eec7882e
@ -1,6 +1,6 @@
|
|||||||
use axum::{Extension, Json};
|
use axum::{Extension, Json};
|
||||||
use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}};
|
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(
|
pub async fn authenticate_google(
|
||||||
Json(req): Json<AuthenticateGooleAccountReq>
|
Json(req): Json<AuthenticateGooleAccountReq>
|
||||||
@ -17,10 +17,10 @@ pub async fn authenticate_with_password(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh_token(
|
pub async fn refresh_token(
|
||||||
Extension(account): Extension<CacheAccount>,
|
Extension(context): Extension<Context>,
|
||||||
Json(refresh_token): Json<RefreshToken>
|
Json(refresh_token): Json<RefreshToken>
|
||||||
) -> ResResult<ResData<RefreshTokenResult>> {
|
) -> ResResult<ResData<RefreshTokenResult>> {
|
||||||
tracing::debug!("刷新token, {:?}", account);
|
tracing::debug!("刷新token, {:?}", context);
|
||||||
validator::validate_params(&refresh_token, "")?;
|
validator::validate_params(&refresh_token, "")?;
|
||||||
service::account::refresh_token(account, refresh_token.token).await
|
service::account::refresh_token(context, refresh_token.token).await
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ pub(crate) fn init() -> Router {
|
|||||||
.get(controller::feedback::get_feedback_list_by_page),
|
.get(controller::feedback::get_feedback_list_by_page),
|
||||||
)
|
)
|
||||||
.layer(axum::middleware::from_fn(
|
.layer(axum::middleware::from_fn(
|
||||||
library::middleware::req_token::authenticate_access_token,
|
library::middleware::req_ctx::authenticate_ctx,
|
||||||
));
|
));
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
|
23
library/src/context.rs
Normal file
23
library/src/context.rs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -5,4 +5,5 @@ pub mod res;
|
|||||||
pub mod middleware;
|
pub mod middleware;
|
||||||
pub mod token;
|
pub mod token;
|
||||||
pub mod social;
|
pub mod social;
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
|
pub mod context;
|
@ -1,4 +1,4 @@
|
|||||||
pub mod req_id;
|
pub mod req_id;
|
||||||
pub mod req_log;
|
pub mod req_log;
|
||||||
pub mod cors;
|
pub mod cors;
|
||||||
pub mod req_token;
|
pub mod req_ctx;
|
@ -2,7 +2,7 @@ use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response
|
|||||||
use http::{header, StatusCode};
|
use http::{header, StatusCode};
|
||||||
use jsonwebtoken::{decode, DecodingKey, Validation};
|
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)] = &[
|
const WHITE_LIST: &[(&str, &str)] = &[
|
||||||
("GET", "/api/v1/users/:id"),
|
("GET", "/api/v1/users/:id"),
|
||||||
@ -11,7 +11,7 @@ const WHITE_LIST: &[(&str, &str)] = &[
|
|||||||
("POST", "/account/sys"),
|
("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),否则继续执行下面的代码
|
// 获取请求的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();
|
||||||
@ -21,6 +21,7 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response
|
|||||||
return next.run(req).await;
|
return next.run(req).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析token
|
||||||
let auth_header = req.headers().get(header::AUTHORIZATION);
|
let auth_header = req.headers().get(header::AUTHORIZATION);
|
||||||
let token = match auth_header {
|
let token = match auth_header {
|
||||||
Some(header_value) => {
|
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(),
|
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();
|
let validation = Validation::default();
|
||||||
match decode::<Claims>(token, &DecodingKey::from_secret(config!().jwt.token_secret.as_bytes()), &validation) {
|
match decode::<Claims>(token, &DecodingKey::from_secret(config!().jwt.token_secret.as_bytes()), &validation) {
|
||||||
Ok(decoded) => {
|
Ok(decoded) => {
|
||||||
@ -41,13 +56,14 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response
|
|||||||
if account.is_none() {
|
if account.is_none() {
|
||||||
return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
|
return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
|
||||||
}
|
}
|
||||||
|
let account = account.unwrap();
|
||||||
// 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在)
|
// 判断token是否有效(注释掉,如果服务因为升级等原因手动重启了,缓存的数据也不再存在)
|
||||||
// let account = account.unwrap();
|
// let account = account.unwrap();
|
||||||
// if account.token != token {
|
// if account.token != token {
|
||||||
// return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
|
// return (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response();
|
||||||
// }
|
// }
|
||||||
// 将Claims附加到请求扩展中,以便后续处理使用
|
// 将Claims附加到请求扩展中,以便后续处理使用
|
||||||
req.extensions_mut().insert(account.unwrap());
|
req.extensions_mut().insert(Context { account: account.account, local: language, token: account.token });
|
||||||
next.run(req).await
|
next.run(req).await
|
||||||
},
|
},
|
||||||
Err(_) => (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(),
|
Err(_) => (StatusCode::UNAUTHORIZED, "Invalid token".to_string()).into_response(),
|
@ -1,5 +1,3 @@
|
|||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use super::response::{ResData, ResErr, ResResult};
|
use super::response::{ResData, ResErr, ResResult};
|
||||||
|
@ -3,6 +3,7 @@ use domain::dto::account::AuthenticateGooleAccountReq;
|
|||||||
use domain::entities::account::Account;
|
use domain::entities::account::Account;
|
||||||
use domain::vo::account::{LoginAccount, RefreshTokenResult};
|
use domain::vo::account::{LoginAccount, RefreshTokenResult};
|
||||||
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
|
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
|
||||||
|
use library::context::Context;
|
||||||
use library::res::response::ResErr::ErrPerm;
|
use library::res::response::ResErr::ErrPerm;
|
||||||
use library::res::response::{ResData, ResErr, ResResult};
|
use library::res::response::{ResData, ResErr, ResResult};
|
||||||
use library::social::google::GOOGLE_SOCIAL;
|
use library::social::google::GOOGLE_SOCIAL;
|
||||||
@ -74,10 +75,10 @@ pub async fn authenticate_google(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh_token(
|
pub async fn refresh_token(
|
||||||
cache_account: CacheAccount,
|
context: Context,
|
||||||
refresh_token: String,
|
refresh_token: String,
|
||||||
) -> ResResult<ResData<RefreshTokenResult>> {
|
) -> ResResult<ResData<RefreshTokenResult>> {
|
||||||
let account = cache_account.account;
|
let account = context.account;
|
||||||
|
|
||||||
if token::verify_refresh_token(&refresh_token).is_err() {
|
if token::verify_refresh_token(&refresh_token).is_err() {
|
||||||
return Err(ResErr::params("refresh_token无效"));
|
return Err(ResErr::params("refresh_token无效"));
|
||||||
|
Loading…
Reference in New Issue
Block a user