refactor: unify authentication state and improve middleware efficiency
- Introduce AuthInfo struct for shared auth state. - Populate AuthInfo in rate_limit_middleware and store in request extensions. - Update AuthenticatedClient extractor to use pre-resolved AuthInfo. - Simplify chat_completions by removing redundant DB lookups.
This commit is contained in:
@@ -1,33 +1,40 @@
|
||||
use axum::{extract::FromRequestParts, http::request::Parts};
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_extra::headers::Authorization;
|
||||
use headers::authorization::Bearer;
|
||||
|
||||
use crate::errors::AppError;
|
||||
|
||||
pub struct AuthenticatedClient {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AuthInfo {
|
||||
pub token: String,
|
||||
pub client_id: String,
|
||||
}
|
||||
|
||||
pub struct AuthenticatedClient {
|
||||
pub info: AuthInfo,
|
||||
}
|
||||
|
||||
impl<S> FromRequestParts<S> for AuthenticatedClient
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = AppError;
|
||||
|
||||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
||||
// Extract bearer token from Authorization header
|
||||
let TypedHeader(Authorization(bearer)) = TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
|
||||
.await
|
||||
.map_err(|_| AppError::AuthError("Missing or invalid bearer token".to_string()))?;
|
||||
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
|
||||
// Retrieve AuthInfo from request extensions, where it was placed by rate_limit_middleware
|
||||
let info = parts
|
||||
.extensions
|
||||
.get::<AuthInfo>()
|
||||
.cloned()
|
||||
.ok_or_else(|| AppError::AuthError("Authentication info not found in request".to_string()))?;
|
||||
|
||||
let token = bearer.token().to_string();
|
||||
Ok(AuthenticatedClient { info })
|
||||
}
|
||||
}
|
||||
|
||||
// Derive client_id from the token prefix
|
||||
let client_id = format!("client_{}", &token[..8.min(token.len())]);
|
||||
impl std::ops::Deref for AuthenticatedClient {
|
||||
type Target = AuthInfo;
|
||||
|
||||
Ok(AuthenticatedClient { token, client_id })
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.info
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user