52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Form, Request
|
|
from fastapi.responses import RedirectResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
|
|
from app.security.auth import authenticate
|
|
from app.security.session import (
|
|
SESSION_COOKIE_NAME,
|
|
clear_session_cookie,
|
|
create_session,
|
|
delete_session,
|
|
set_session_cookie,
|
|
)
|
|
|
|
|
|
router = APIRouter()
|
|
templates = Jinja2Templates(directory="app/admin/templates")
|
|
|
|
|
|
@router.get("/login")
|
|
def login_page(request: Request, next: str | None = None): # noqa: A002
|
|
return templates.TemplateResponse(
|
|
"login.html",
|
|
{"request": request, "error": "", "next": next or "/admin"},
|
|
)
|
|
|
|
|
|
@router.post("/login")
|
|
def login_action(request: Request, username: str = Form(...), password: str = Form(...), next: str = Form("/admin")):
|
|
user_id = authenticate(username, password, request=request)
|
|
if not user_id:
|
|
return templates.TemplateResponse(
|
|
"login.html",
|
|
{"request": request, "error": "用户名或密码错误", "next": next},
|
|
status_code=401,
|
|
)
|
|
session_id = create_session(user_id, request)
|
|
response = RedirectResponse(next or "/admin", status_code=303)
|
|
set_session_cookie(response, session_id)
|
|
return response
|
|
|
|
|
|
@router.get("/logout")
|
|
def logout(request: Request):
|
|
session_id = request.cookies.get(SESSION_COOKIE_NAME)
|
|
if session_id:
|
|
delete_session(session_id)
|
|
response = RedirectResponse("/login", status_code=303)
|
|
clear_session_cookie(response)
|
|
return response
|