Files
hms/crates/erp-core/src/request_info.rs
iven a0b72b0f73
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
feat: Iteration 1 — 审计日志IP记录、文件上传、医护端API、小程序角色切换
Iteration 1 六项任务全部完成:

1. 审计日志IP记录 — task_local RequestInfo 自动注入 IP/user_agent
2. 文件上传服务 — multipart 上传 + ServeDir 静态文件服务
3. 医护端后端API — 医生工作台仪表盘 + 患者标签CRUD + 会话已读
4. 小程序角色切换 — 登录后根据角色跳转医护台/患者首页
5. 小程序安全加固 — secure-storage 开发模式警告
6. 讨论记录归档 — docs/discussions/
2026-04-26 13:13:25 +08:00

55 lines
1.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// 请求来源信息IP 地址 + User-Agent
///
/// 通过 `tokio::task_local!` 在请求生命周期内传递,
/// JWT 中间件设置,审计服务自动读取。
#[derive(Debug, Clone, Default)]
pub struct RequestInfo {
pub ip_address: Option<String>,
pub user_agent: Option<String>,
}
tokio::task_local! {
/// 当前请求的来源信息。
///
/// 在 JWT 中间件中通过 `REQUEST_INFO.scope(info, future)` 设置,
/// 在 `audit_service::record()` 中自动读取。
pub static REQUEST_INFO: RequestInfo;
}
impl RequestInfo {
/// 从 HTTP 请求头中提取 IP 地址和 User-Agent。
///
/// IP 优先级X-Forwarded-For > X-Real-IP > 直接连接(不记录)。
pub fn from_headers(headers: &axum::http::HeaderMap) -> Self {
let ip_address = headers
.get("X-Forwarded-For")
.and_then(|v| v.to_str().ok())
.map(|s| {
// X-Forwarded-For 可能包含多个 IP取第一个客户端真实 IP
s.split(',').next().unwrap_or(s).trim().to_string()
})
.or_else(|| {
headers
.get("X-Real-IP")
.and_then(|v| v.to_str().ok())
.map(|s| s.trim().to_string())
});
let user_agent = headers
.get("user-agent")
.and_then(|v| v.to_str().ok())
.map(|s| s.to_string());
Self {
ip_address,
user_agent,
}
}
/// 尝试从 task_local 中读取当前请求信息。
/// 如果不在请求上下文中(如后台任务),返回 None。
pub fn try_current() -> Option<Self> {
REQUEST_INFO.try_with(|info| info.clone()).ok()
}
}