fix: harden authentication system (JWT, cookies, rate limiting, password policy)

- Replace hardcoded JWT secret with randomly generated key persisted to file
- Replace hardcoded default password with random password shown in logs
- Migrate token storage from localStorage to HttpOnly SameSite=strict cookie
- Add IP-based login rate limiter (5 attempts / 15 min, 429 on lockout)
- Add token_version for JWT revocation on password change
- Add password strength validation (min 6 chars, 3+ unique characters)
- Inject decoded user payload into request.state.user in auth middleware
- Add /api/auth/me and /api/auth/logout endpoints
- Narrow auth middleware exception handling (JWTError only, not all Exception)
- Update updated_at timestamp on password change
- Remove localStorage token management from frontend (axios, router, store)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
祀梦
2026-05-17 15:54:45 +08:00
parent 1047bcece9
commit 9d4d869d57
13 changed files with 249 additions and 75 deletions

View File

@@ -1,15 +1,28 @@
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, field_validator
class LoginRequest(BaseModel):
password: str = Field(..., min_length=1, max_length=100)
class TokenResponse(BaseModel):
access_token: str
token_type: str = "bearer"
class LoginResponse(BaseModel):
message: str = "登录成功"
class ChangePasswordRequest(BaseModel):
old_password: str = Field(..., min_length=1, max_length=100)
new_password: str = Field(..., min_length=1, max_length=100)
new_password: str = Field(..., min_length=6, max_length=100)
@field_validator("new_password")
@classmethod
def validate_password_strength(cls, v: str) -> str:
if len(v) < 6:
raise ValueError("密码长度至少6位")
if len(set(v)) < 3:
raise ValueError("密码不能过于简单需包含至少3种不同字符")
return v
class AuthStatusResponse(BaseModel):
authenticated: bool
user_id: str