feat(routes): AuthUser extractor validating Bearer JWT
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9d93a33bae
commit
29cbf524e9
30
Server/src/routes/extract.rs
Normal file
30
Server/src/routes/extract.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@
|
||||
//! 可用环境变量 `STATIC_DIR` 覆盖。
|
||||
|
||||
mod client;
|
||||
mod extract;
|
||||
mod web;
|
||||
|
||||
use axum::Router;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user