feat(routes): AuthUser extractor validating Bearer JWT

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cc 2026-06-24 21:08:42 +08:00
parent 9d93a33bae
commit 29cbf524e9
2 changed files with 31 additions and 0 deletions

View File

@ -0,0 +1,30 @@
//! 鉴权提取器:从 `Authorization: Bearer <jwt>` 解出当前用户名。
//!
//! axum 0.8 的 `FromRequestParts` 用原生 `async fn`,无需 `#[async_trait]`。
use axum::extract::FromRequestParts;
use axum::http::{header, request::Parts, StatusCode};
use crate::auth;
/// 受保护接口的参数:产出已校验的用户名;缺失/非法/过期 token 一律 `401`。
pub struct AuthUser(pub String);
impl<S> FromRequestParts<S> for AuthUser
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let header = parts
.headers
.get(header::AUTHORIZATION)
.and_then(|v| v.to_str().ok())
.ok_or(StatusCode::UNAUTHORIZED)?;
let token = header.strip_prefix("Bearer ").ok_or(StatusCode::UNAUTHORIZED)?;
auth::verify_token(token)
.map(AuthUser)
.ok_or(StatusCode::UNAUTHORIZED)
}
}

View File

@ -9,6 +9,7 @@
//! 可用环境变量 `STATIC_DIR` 覆盖。
mod client;
mod extract;
mod web;
use axum::Router;