feat(auth): 后台登录改为滑动会话
- JWT 记录 iat,exp=min(now+24h, iat+7d) - 已认证请求自动续签 httpOnly Cookie - 新增 ACCESS_TOKEN_IDLE_HOURS / ACCESS_TOKEN_MAX_HOURS
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from fastapi import APIRouter, Depends, Request, Response
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -21,7 +19,7 @@ from ..schemas import (
|
||||
SmsCodeResponse,
|
||||
TokenResponse,
|
||||
)
|
||||
from ..security import ACCESS_TOKEN_EXPIRE_HOURS, create_access_token, verify_password
|
||||
from ..security import issue_access_token, verify_password
|
||||
from ..services.dc_auth_service import (
|
||||
APP_ID,
|
||||
CHALLENGE_PURPOSE,
|
||||
@@ -37,12 +35,10 @@ from ..services.login_sms_service import (
|
||||
send_login_sms_code,
|
||||
verify_login_sms_code,
|
||||
)
|
||||
from ..session import clear_session_cookie, set_session_cookie
|
||||
|
||||
router = APIRouter(prefix="/api/auth", tags=["认证"])
|
||||
|
||||
# Cookie 安全配置(生产环境 HTTPS 部署时设置 COOKIE_SECURE=true)
|
||||
_COOKIE_SECURE = os.getenv("COOKIE_SECURE", "false").lower() == "true"
|
||||
|
||||
|
||||
def _find_user(db: Session, username_value: str) -> User | None:
|
||||
"""用户名只 trim,不做大小写折叠、不限制字符集。
|
||||
@@ -75,18 +71,6 @@ def _request_origin(request: Request) -> str:
|
||||
return str(request.base_url).rstrip("/")
|
||||
|
||||
|
||||
def _set_auth_cookie(response: Response, token: str) -> None:
|
||||
response.set_cookie(
|
||||
key="access_token",
|
||||
value=token,
|
||||
httponly=True,
|
||||
secure=_COOKIE_SECURE,
|
||||
samesite="lax",
|
||||
max_age=ACCESS_TOKEN_EXPIRE_HOURS * 3600,
|
||||
path="/",
|
||||
)
|
||||
|
||||
|
||||
def _issue_session(
|
||||
db: Session,
|
||||
response: Response,
|
||||
@@ -94,8 +78,8 @@ def _issue_session(
|
||||
method: str,
|
||||
device_id: str = "",
|
||||
) -> TokenResponse:
|
||||
token = create_access_token({"sub": str(user.id), "role": user.role})
|
||||
_set_auth_cookie(response, token)
|
||||
issued = issue_access_token({"sub": str(user.id), "role": user.role})
|
||||
set_session_cookie(response, issued.token, issued.expires_at)
|
||||
|
||||
detail = f"method={method}"
|
||||
if device_id:
|
||||
@@ -112,7 +96,7 @@ def _issue_session(
|
||||
db.commit()
|
||||
|
||||
return TokenResponse(
|
||||
access_token=token,
|
||||
access_token=issued.token,
|
||||
role=user.role,
|
||||
username=user.username,
|
||||
permissions=get_user_permissions(user),
|
||||
@@ -252,7 +236,7 @@ def logout(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
response.delete_cookie(key="access_token", path="/")
|
||||
clear_session_cookie(response)
|
||||
db.add(
|
||||
AuditLog(
|
||||
user_id=current_user.id,
|
||||
|
||||
Reference in New Issue
Block a user