feat: add login, session cookies, and get_current_user

This commit is contained in:
Indiana
2026-07-20 15:26:58 +00:00
parent fa725f1a0e
commit a0723b5237
6 changed files with 136 additions and 4 deletions

View File

@@ -1,11 +1,15 @@
from fastapi import APIRouter, Depends, HTTPException, status
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db import get_db
from app.deps import SESSION_COOKIE_NAME, get_current_user
from app.models.auth_session import AuthSession, SESSION_TTL, generate_session_token
from app.models.user import User
from app.schemas import RegisterRequest, UserOut
from app.security import hash_password
from app.schemas import LoginRequest, RegisterRequest, UserOut
from app.security import hash_password, verify_password
router = APIRouter(prefix="/auth", tags=["auth"])
@@ -25,3 +29,38 @@ async def register(payload: RegisterRequest, db: AsyncSession = Depends(get_db))
await db.commit()
await db.refresh(user)
return user
@router.post("/login", response_model=UserOut)
async def login(payload: LoginRequest, response: Response, db: AsyncSession = Depends(get_db)):
user = await db.scalar(select(User).where(User.username == payload.username))
if user is None or not verify_password(payload.password, user.password_hash):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid credentials")
raw_token, token_hash = generate_session_token()
session = AuthSession(
user_id=user.id,
token_hash=token_hash,
expires_at=datetime.now(timezone.utc) + SESSION_TTL,
)
db.add(session)
await db.commit()
response.set_cookie(
SESSION_COOKIE_NAME,
raw_token,
httponly=True,
samesite="lax",
max_age=int(SESSION_TTL.total_seconds()),
)
return user
@router.post("/logout", status_code=status.HTTP_204_NO_CONTENT)
async def logout(response: Response):
response.delete_cookie(SESSION_COOKIE_NAME)
@router.get("/me", response_model=UserOut)
async def me(user: User = Depends(get_current_user)):
return user