refactor: extract session parsing to auth/session.rs and db error helpers to api/utils.rs
This commit is contained in:
parent
9da060ac32
commit
d3be04bcec
@ -5,6 +5,7 @@ use dioxus::prelude::*;
|
||||
use http::header::{HeaderValue, SET_COOKIE};
|
||||
|
||||
use crate::auth::{password, session};
|
||||
use crate::auth::session::get_session_from_ctx;
|
||||
use crate::db::pool::get_conn;
|
||||
use crate::models::user::{PublicUser, User, UserRole};
|
||||
|
||||
@ -36,20 +37,6 @@ fn validate_password(password: &str) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
||||
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
||||
let mut parts = pair.splitn(2, '=');
|
||||
let name = parts.next()?.trim();
|
||||
let value = parts.next()?.trim();
|
||||
if name == "session" {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct AuthResponse {
|
||||
pub success: bool,
|
||||
@ -216,17 +203,7 @@ pub async fn login(username: String, password: String) -> Result<AuthResponse, S
|
||||
|
||||
#[server(Logout, "/api")]
|
||||
pub async fn logout() -> Result<AuthResponse, ServerFnError> {
|
||||
let token = if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||
let parts = ctx.parts_mut();
|
||||
parts
|
||||
.headers
|
||||
.get("cookie")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.and_then(parse_session_token)
|
||||
.map(|s| s.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let token = get_session_from_ctx();
|
||||
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("Logout DB connection failed: {:?}", e);
|
||||
@ -266,17 +243,7 @@ pub struct CurrentUserResponse {
|
||||
|
||||
#[server(GetCurrentUser, "/api")]
|
||||
pub async fn get_current_user() -> Result<CurrentUserResponse, ServerFnError> {
|
||||
let token = if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||
let parts = ctx.parts_mut();
|
||||
parts
|
||||
.headers
|
||||
.get("cookie")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.and_then(parse_session_token)
|
||||
.map(|s| s.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let token = get_session_from_ctx();
|
||||
|
||||
let Some(token) = token else {
|
||||
return Ok(CurrentUserResponse { user: None });
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod auth;
|
||||
pub mod posts;
|
||||
pub mod utils;
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::auth::session::get_session_from_ctx;
|
||||
use crate::api::utils::{db_conn_error, query_error};
|
||||
use crate::db::pool::get_conn;
|
||||
use crate::models::post::{Post, PostStats, PostStatus, Tag};
|
||||
use crate::models::user::{User, UserRole};
|
||||
@ -10,42 +12,15 @@ use crate::models::user::{User, UserRole};
|
||||
// Server-side helpers (only compiled when server feature is enabled)
|
||||
// ============================================================================
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
||||
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
||||
let mut parts = pair.splitn(2, '=');
|
||||
let name = parts.next()?.trim();
|
||||
let value = parts.next()?.trim();
|
||||
if name == "session" {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
async fn get_current_admin_user() -> Result<User, ServerFnError> {
|
||||
let token = if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||
let parts = ctx.parts_mut();
|
||||
parts
|
||||
.headers
|
||||
.get("cookie")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.and_then(parse_session_token)
|
||||
.map(|s| s.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let token = get_session_from_ctx();
|
||||
|
||||
let Some(token) = token else {
|
||||
return Err(ServerFnError::new("未登录"));
|
||||
};
|
||||
|
||||
let client = get_conn().await.map_err(|e| {
|
||||
tracing::error!("DB connection failed: {:?}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
})?;
|
||||
let client = get_conn().await.map_err(db_conn_error)?;
|
||||
|
||||
let row = client
|
||||
.query_opt(
|
||||
@ -56,10 +31,7 @@ async fn get_current_admin_user() -> Result<User, ServerFnError> {
|
||||
&[&token],
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("query failed: {:?}", e);
|
||||
ServerFnError::new(format!("查询失败: {}", e))
|
||||
})?;
|
||||
.map_err(query_error)?;
|
||||
|
||||
let user = match row {
|
||||
Some(row) => {
|
||||
|
||||
15
src/api/utils.rs
Normal file
15
src/api/utils.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![allow(clippy::unused_unit)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn db_conn_error(e: impl std::fmt::Display) -> ServerFnError {
|
||||
tracing::error!("DB connection failed: {}", e);
|
||||
ServerFnError::new(format!("数据库连接失败: {}", e))
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn query_error(e: impl std::fmt::Display) -> ServerFnError {
|
||||
tracing::error!("Query failed: {}", e);
|
||||
ServerFnError::new(format!("查询失败: {}", e))
|
||||
}
|
||||
@ -10,3 +10,31 @@ pub fn generate_token() -> String {
|
||||
pub fn default_expiry() -> DateTime<Utc> {
|
||||
Utc::now() + Duration::days(30)
|
||||
}
|
||||
|
||||
pub fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
||||
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
||||
let mut parts = pair.splitn(2, '=');
|
||||
let name = parts.next()?.trim();
|
||||
let value = parts.next()?.trim();
|
||||
if name == "session" {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn get_session_from_ctx() -> Option<String> {
|
||||
use dioxus::fullstack::FullstackContext;
|
||||
|
||||
FullstackContext::current().and_then(|ctx| {
|
||||
let parts = ctx.parts_mut();
|
||||
parts
|
||||
.headers
|
||||
.get("cookie")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.and_then(parse_session_token)
|
||||
.map(|s| s.to_string())
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user