Automated Action f84493a558 Implement user authentication system with FastAPI and SQLite
- Create user model and database connection
- Set up Alembic migrations
- Implement JWT token authentication
- Add routes for registration, login, refresh, and user profile
- Create health endpoint
- Configure CORS
- Update README with setup and usage instructions
2025-06-02 21:28:50 +00:00

60 lines
1.8 KiB
Python

from datetime import datetime, timedelta
from typing import Any, Optional
import os
from jose import jwt
from pydantic import ValidationError
from app.schemas.token import TokenPayload
# Get JWT settings from environment variables
SECRET_KEY = os.getenv("SECRET_KEY", "supersecretkey")
ALGORITHM = os.getenv("ALGORITHM", "HS256")
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", 30))
REFRESH_TOKEN_EXPIRE_DAYS = int(os.getenv("REFRESH_TOKEN_EXPIRE_DAYS", 7))
def create_access_token(subject: str | Any, expires_delta: Optional[timedelta] = None) -> str:
"""
Create a new JWT access token
"""
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def create_refresh_token(subject: str | Any, expires_delta: Optional[timedelta] = None) -> str:
"""
Create a new JWT refresh token
"""
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def verify_token(token: str) -> Optional[TokenPayload]:
"""
Verify and decode a JWT token
"""
try:
payload = jwt.decode(
token, SECRET_KEY, algorithms=[ALGORITHM]
)
token_data = TokenPayload(**payload)
if datetime.fromtimestamp(token_data.exp) < datetime.utcnow():
return None
return token_data
except (jwt.JWTError, ValidationError):
return None