Phase 2.3: JWT Authentication implementation
- Implemented JWT-based authentication system with access and refresh tokens - Added password hashing service using PBKDF2 - Created authentication handlers: register, login, refresh, logout - Added protected routes with JWT middleware - Created user profile handlers - Fixed all compilation errors - Added integration tests for authentication endpoints - Added reqwest dependency for testing - Created test script and environment example documentation All changes: - backend/src/auth/: Complete auth module (JWT, password, claims) - backend/src/handlers/: Auth, users, and health handlers - backend/src/middleware/: JWT authentication middleware - backend/src/config/: Added AppState with Clone derive - backend/src/main.rs: Fixed imports and added auth routes - backend/src/db/mod.rs: Changed error handling to anyhow::Result - backend/Cargo.toml: Added reqwest for testing - backend/tests/auth_tests.rs: Integration tests - thoughts/: Documentation updates (STATUS.md, env.example, test_auth.sh)
This commit is contained in:
parent
154c3d1152
commit
8b2c13501f
19 changed files with 935 additions and 98 deletions
51
backend/src/middleware/auth.rs
Normal file
51
backend/src/middleware/auth.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
use axum::{
|
||||
extract::{Request, State},
|
||||
http::StatusCode,
|
||||
middleware::Next,
|
||||
response::Response,
|
||||
};
|
||||
use crate::auth::claims::AccessClaims;
|
||||
use crate::config::AppState;
|
||||
|
||||
pub async fn jwt_auth_middleware(
|
||||
State(state): State<AppState>,
|
||||
mut req: Request,
|
||||
next: Next,
|
||||
) -> Result<Response, StatusCode> {
|
||||
let headers = req.headers();
|
||||
|
||||
// Extract Authorization header
|
||||
let auth_header = headers
|
||||
.get("Authorization")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
// Check Bearer token format
|
||||
if !auth_header.starts_with("Bearer ") {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
let token = &auth_header[7..]; // Remove "Bearer " prefix
|
||||
|
||||
// Verify token
|
||||
let claims = state
|
||||
.jwt_service
|
||||
.verify_access_token(token)
|
||||
.map_err(|_| StatusCode::UNAUTHORIZED)?;
|
||||
|
||||
// Add claims to request extensions for handlers to use
|
||||
req.extensions_mut().insert(claims);
|
||||
|
||||
Ok(next.run(req).await)
|
||||
}
|
||||
|
||||
// Extension method to extract claims from request
|
||||
pub trait RequestClaimsExt {
|
||||
fn claims(&self) -> Option<&AccessClaims>;
|
||||
}
|
||||
|
||||
impl RequestClaimsExt for Request {
|
||||
fn claims(&self) -> Option<&AccessClaims> {
|
||||
self.extensions().get::<AccessClaims>()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue