37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
|
|
import logging
|
||
|
|
|
||
|
|
from fastapi import APIRouter
|
||
|
|
from pydantic import BaseModel, Field
|
||
|
|
|
||
|
|
from response import ApiResponse
|
||
|
|
from security import create_access_token, verify_credentials
|
||
|
|
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/api/auth", tags=["auth"])
|
||
|
|
|
||
|
|
|
||
|
|
class LoginBody(BaseModel):
|
||
|
|
username: str = Field(..., min_length=1, max_length=64)
|
||
|
|
password: str = Field(..., min_length=1, max_length=128)
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/login", response_model=ApiResponse)
|
||
|
|
def login(body: LoginBody):
|
||
|
|
"""控制台登录,成功后返回 JWT(有效期 12 小时)"""
|
||
|
|
if not verify_credentials(body.username.strip(), body.password):
|
||
|
|
logger.warning("Login failed for username=%s", body.username)
|
||
|
|
return ApiResponse(code=0, msg="用户名或密码错误", data=None)
|
||
|
|
token = create_access_token()
|
||
|
|
ttl_seconds = 12 * 60 * 60
|
||
|
|
logger.info("User %s logged in", body.username.strip())
|
||
|
|
return ApiResponse(
|
||
|
|
code=1,
|
||
|
|
msg="success",
|
||
|
|
data={
|
||
|
|
"access_token": token,
|
||
|
|
"token_type": "bearer",
|
||
|
|
"expires_in": ttl_seconds,
|
||
|
|
},
|
||
|
|
)
|