Step 5: Authentication System & Environment Variables

- Implemented JWT authentication in Console backend
- Added .env file for environment variable management
- Updated docker-compose to use .env variables
- Created authentication endpoints (login/logout/me)
- Added protected route middleware
- Created ARCHITECTURE.md with Kafka as main messaging platform
- Defined Kafka for both events and task queues
- Redis dedicated for caching and session management

Test credentials:
- admin/admin123
- user/user123

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jungwoo choi
2025-09-10 16:36:47 +09:00
parent 4b2be7ccaf
commit 315eeea2ae
6 changed files with 378 additions and 20 deletions

View File

@ -1,10 +1,17 @@
from fastapi import FastAPI, HTTPException, Request, Response
from fastapi import FastAPI, HTTPException, Request, Response, Depends, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import OAuth2PasswordRequestForm
import uvicorn
from datetime import datetime
from datetime import datetime, timedelta
import httpx
import os
from typing import Any
from auth import (
Token, UserLogin, UserInDB,
verify_password, get_password_hash,
create_access_token, get_current_user,
ACCESS_TOKEN_EXPIRE_MINUTES
)
app = FastAPI(
title="Console API Gateway",
@ -40,6 +47,58 @@ async def health_check():
"timestamp": datetime.now().isoformat()
}
# Authentication endpoints
@app.post("/api/auth/login", response_model=Token)
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
"""Login endpoint for authentication"""
# For demo purposes - in production, check against database
# This is temporary until we integrate with Users service
demo_users = {
"admin": {
"username": "admin",
"hashed_password": get_password_hash("admin123"),
"email": "admin@site11.com",
"full_name": "Administrator",
"is_active": True
},
"user": {
"username": "user",
"hashed_password": get_password_hash("user123"),
"email": "user@site11.com",
"full_name": "Test User",
"is_active": True
}
}
user = demo_users.get(form_data.username)
if not user or not verify_password(form_data.password, user["hashed_password"]):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user["username"]}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/api/auth/me")
async def get_me(current_user = Depends(get_current_user)):
"""Get current user information"""
return {
"username": current_user.username,
"email": f"{current_user.username}@site11.com",
"is_active": True
}
@app.post("/api/auth/logout")
async def logout(current_user = Depends(get_current_user)):
"""Logout endpoint"""
# In a real application, you might want to blacklist the token
return {"message": "Successfully logged out"}
@app.get("/api/status")
async def system_status():
services_status = {}
@ -65,10 +124,19 @@ async def system_status():
"timestamp": datetime.now().isoformat()
}
# Protected endpoint example
@app.get("/api/protected")
async def protected_route(current_user = Depends(get_current_user)):
"""Example of a protected route"""
return {
"message": "This is a protected route",
"user": current_user.username
}
# API Gateway - Route to Users service
@app.api_route("/api/users/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
async def proxy_to_users(path: str, request: Request):
"""Proxy requests to Users service"""
async def proxy_to_users(path: str, request: Request, current_user = Depends(get_current_user)):
"""Proxy requests to Users service (protected)"""
try:
async with httpx.AsyncClient() as client:
# Build the target URL