40 lines
1.2 KiB
Rust
40 lines
1.2 KiB
Rust
use axum::{
|
|
extract::FromRequestParts,
|
|
http::{request::Parts, StatusCode},
|
|
};
|
|
use std::future::Future;
|
|
|
|
pub struct RequireAuth(pub crate::jwt::Claims);
|
|
|
|
impl<S> FromRequestParts<S> for RequireAuth
|
|
where
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = (StatusCode, &'static str);
|
|
|
|
fn from_request_parts(
|
|
parts: &mut Parts,
|
|
_state: &S,
|
|
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
|
|
let token = parts
|
|
.headers
|
|
.get("Authorization")
|
|
.and_then(|value| value.to_str().ok())
|
|
.filter(|value| value.starts_with("Bearer "))
|
|
.map(|header| header.trim_start_matches("Bearer ").to_string());
|
|
|
|
async move {
|
|
let token = match token {
|
|
Some(token) => token,
|
|
None => return Err((StatusCode::UNAUTHORIZED, "Missing Bearer token")),
|
|
};
|
|
|
|
let jwt_secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");
|
|
|
|
match crate::jwt::verify_access_token(&token, &jwt_secret) {
|
|
Ok(claims) => Ok(RequireAuth(claims)),
|
|
Err(_) => Err((StatusCode::UNAUTHORIZED, "Invalid or expired token")),
|
|
}
|
|
}
|
|
}
|
|
}
|