from fastapi import Depends, HTTPException, Request, status from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer from sqlalchemy.orm import Session from app.config import settings from app.database import get_db from app.models.user import User _serializer = URLSafeTimedSerializer(settings.secret_key, salt="habit-session") SESSION_MAX_AGE_SECONDS = 60 * 60 * 24 * 30 # 30일 def create_session_token(user_id: int) -> str: return _serializer.dumps({"user_id": user_id}) def get_session_user_id(request: Request) -> int | None: token = request.cookies.get(settings.session_cookie_name) if not token: return None try: data = _serializer.loads(token, max_age=SESSION_MAX_AGE_SECONDS) except (BadSignature, SignatureExpired): return None return data.get("user_id") def require_login(request: Request, db: Session = Depends(get_db)) -> User: user_id = get_session_user_id(request) user = db.get(User, user_id) if user_id is not None else None if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="로그인이 필요합니다") return user def get_current_user_optional(request: Request, db: Session) -> User | None: user_id = get_session_user_id(request) return db.get(User, user_id) if user_id is not None else None def is_logged_in(request: Request) -> bool: return get_session_user_id(request) is not None