WealthFromAI's picture
FORGE-X: Upload source (e30bed1a-api.zip)
03df5ce verified
Raw
History Blame Contribute Delete
1.87 kB
"""
Simple JWT auth — swap for OAuth2/API keys in production.
"""
import os
from datetime import datetime, timedelta, timezone
from typing import Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from jose import JWTError, jwt
from passlib.context import CryptContext
SECRET_KEY = os.getenv("SECRET_KEY", "changeme-in-production-please")
ALGORITHM = os.getenv("ALGORITHM", "HS256")
EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBearer()
# Demo users — replace with real DB lookup
USERS: dict[str, str] = {
"admin": pwd_context.hash("admin123"),
"demo": pwd_context.hash("demo123"),
}
def verify_password(username: str, password: str) -> bool:
hashed = USERS.get(username)
if not hashed:
return False
return pwd_context.verify(password, hashed)
def create_access_token(data: dict) -> str:
to_encode = data.copy()
expire = datetime.now(timezone.utc) + timedelta(minutes=EXPIRE_MINUTES)
to_encode["exp"] = expire
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
token = credentials.credentials
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: Optional[str] = payload.get("sub")
if not username:
raise HTTPException(status_code=401, detail="Invalid token payload")
return username
except JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
headers={"WWW-Authenticate": "Bearer"},
)