添加日志

This commit is contained in:
ChengCan
2026-03-26 11:25:34 +08:00
parent 3e3f4390a6
commit cff7ddf220
9 changed files with 351 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
import hashlib
import logging
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy import text
from sqlalchemy.orm import Session
@@ -17,10 +18,22 @@ except ModuleNotFoundError:
router = APIRouter(prefix="/auth", tags=["auth"])
logger = logging.getLogger("app.auth")
def _mask_username(username: str) -> str:
if len(username) <= 2:
return "*" * len(username)
return f"{username[:2]}***"
@router.post("/login", response_model=LoginResponse)
def login(payload: LoginRequest, db: Session = Depends(get_db)) -> LoginResponse:
def login(
payload: LoginRequest,
request: Request,
db: Session = Depends(get_db),
) -> LoginResponse:
username_masked = _mask_username(payload.username)
with db.begin():
row = (
db.execute(
@@ -45,12 +58,31 @@ def login(payload: LoginRequest, db: Session = Depends(get_db)) -> LoginResponse
.first()
)
if not row:
logger.warning(
"login failed",
extra={
"event": "login",
"request_id": getattr(request.state, "request_id", None),
"username": username_masked,
"reason": "invalid_username_or_password",
},
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="invalid username or password",
)
if int(row["auth_status"]) != 1 or int(row["user_status"]) != 1:
logger.warning(
"login failed",
extra={
"event": "login",
"request_id": getattr(request.state, "request_id", None),
"username": username_masked,
"user_id": int(row["user_id"]),
"reason": "account_disabled",
},
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="account is disabled",
@@ -59,6 +91,15 @@ def login(payload: LoginRequest, db: Session = Depends(get_db)) -> LoginResponse
# Seed data currently stores sha256; migrate to bcrypt/argon2 in production.
password_hash = hashlib.sha256(payload.password.encode("utf-8")).hexdigest()
if not row["password_hash"] or password_hash != row["password_hash"]:
logger.warning(
"login failed",
extra={
"event": "login",
"request_id": getattr(request.state, "request_id", None),
"username": username_masked,
"reason": "invalid_username_or_password",
},
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="invalid username or password",
@@ -88,6 +129,15 @@ def login(payload: LoginRequest, db: Session = Depends(get_db)) -> LoginResponse
)
access_token, expires_in = create_access_token(user_id=int(row["user_id"]))
logger.info(
"login succeeded",
extra={
"event": "login",
"request_id": getattr(request.state, "request_id", None),
"user_id": int(row["user_id"]),
"username": username_masked,
},
)
return LoginResponse(
access_token=access_token,
expires_in=expires_in,