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` 覆盖。
|
//! 可用环境变量 `STATIC_DIR` 覆盖。
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
|
mod extract;
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user