增加token刷新接口

This commit is contained in:
李运家 2024-06-06 17:56:27 +08:00
parent 86bcdfae26
commit 6f0c0e5f96
6 changed files with 70 additions and 17 deletions

View File

@ -1,6 +1,6 @@
use axum::Json; use axum::{Extension, Json};
use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword}, vo::account::LoginAccount}; use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}};
use library::resp::response::{ ResData, ResResult}; use library::{cache::account_cache::CacheAccount, resp::response::{ ResData, ResResult}};
use validator::Validate; use validator::Validate;
pub async fn authenticate_google( pub async fn authenticate_google(
@ -17,4 +17,12 @@ pub async fn authenticate_with_password(
req.validate()?; req.validate()?;
service::sys_account::authenticate_with_password(req).await service::sys_account::authenticate_with_password(req).await
} }
pub async fn refresh_token(
Extension(account): Extension<CacheAccount>,
Json(refresh_token): Json<RefreshToken>
) -> ResResult<ResData<RefreshTokenResult>> {
tracing::debug!("刷新token, {:?}", account);
service::account::refresh_token(account, refresh_token.token).await
}

View File

@ -17,6 +17,10 @@ pub(crate) fn init() -> Router {
"/account/sys", "/account/sys",
post(controller::account::authenticate_with_password), post(controller::account::authenticate_with_password),
) )
.route(
"/account/refresh-token",
post(controller::account::refresh_token)
)
.route( .route(
"/feedback", "/feedback",
post(controller::feedback::add_feedback) post(controller::feedback::add_feedback)

View File

@ -14,3 +14,8 @@ pub struct AuthenticateGooleAccountReq {
#[validate(required(message = "用户ID Token不能为空"), length(min = 1, message = "用户ID Token不能为空"))] #[validate(required(message = "用户ID Token不能为空"), length(min = 1, message = "用户ID Token不能为空"))]
pub id_token: Option<String>, pub id_token: Option<String>,
} }
#[derive(Debug, Validate, Deserialize, Serialize)]
pub struct RefreshToken {
pub token: String,
}

View File

@ -14,4 +14,10 @@ pub struct LoginAccount {
pub email: Option<String>, pub email: Option<String>,
pub token: String, pub token: String,
pub refresh_token: String, pub refresh_token: String,
} }
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RefreshTokenResult {
pub token: String,
pub refresh_token: String,
}

View File

@ -47,7 +47,7 @@ pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response
// 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); req.extensions_mut().insert(account.unwrap());
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(),

View File

@ -1,11 +1,12 @@
use chrono::Utc; use chrono::Utc;
use domain::dto::account::AuthenticateGooleAccountReq; use domain::dto::account::AuthenticateGooleAccountReq;
use domain::entities::account::Account; use domain::entities::account::Account;
use domain::vo::account::LoginAccount; use domain::vo::account::{LoginAccount, RefreshTokenResult};
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE}; use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
use library::resp::response::ResErr::ErrPerm; use library::resp::response::ResErr::ErrPerm;
use library::resp::response::{ResErr, ResData, ResResult}; use library::resp::response::{ResData, ResErr, ResResult};
use library::social::google::GOOGLE_SOCIAL; use library::social::google::GOOGLE_SOCIAL;
use library::token::{generate_refresh_token, generate_token};
use library::{db, token}; use library::{db, token};
pub async fn authenticate_google( pub async fn authenticate_google(
@ -59,15 +60,44 @@ pub async fn authenticate_google(
) )
.await; .await;
let login_account = LoginAccount{ let login_account = LoginAccount {
username: account.username, username: account.username,
display_name: account.display_name, display_name: account.display_name,
avatar_url: account.avatar_url, avatar_url: account.avatar_url,
metadata: account.metadata, metadata: account.metadata,
wallet: account.wallet, wallet: account.wallet,
email: account.email, email: account.email,
token, token,
refresh_token refresh_token,
}; };
return Ok(ResData::some(login_account)); return Ok(ResData::some(login_account));
} }
pub async fn refresh_token(
cache_account: CacheAccount,
refresh_token: String,
) -> ResResult<ResData<RefreshTokenResult>> {
let account = cache_account.account;
if token::verify_refresh_token(&refresh_token).is_err() {
return Err(ResErr::params("refresh_token无效"));
}
let refresh_token = RefreshTokenResult {
token: generate_token(&account.id),
refresh_token: generate_refresh_token(&account.id),
};
LOGIN_CACHE.remove(&account.id).await;
LOGIN_CACHE
.insert(
account.id.to_owned(),
CacheAccount {
account: account.clone(),
token: refresh_token.token.to_owned(),
},
)
.await;
Ok(ResData::some(refresh_token))
}