fix(security): P1/P2 审计修复 + JWT HttpOnly Cookie 双模认证 + 限流

- P0/P1 审计修复: 滑块验证码不再下发 x_position/成败即销毁 key、
  user-login 补失败计数+滑块门控、限流标识改 X-Real-IP、
  百度翻译 appkey 环境化、ChangeEmail/ChangePhone 补调 avalidate、
  logs/tasks.py Count(filter=Q) 修复、chat 收藏 SSRF 内网黑名单
- P1 #6/7: token_blacklist + ROTATE_REFRESH_TOKENS 开启,
  /user/token/refresh/ 挂载
- #2 JWT HttpOnly Cookie 双模认证: user/cookie_auth.py 种/清 Cookie,
  user/authentication.py CookieOrHeaderJWTAuthentication(Bearer 优先/_COOKIE 兜底),
  user/views/token.py CookieTokenRefreshView + UserLogoutAPIView(/user/logout/),
  create_standardized_response 自动对含 token 的响应种 Cookie,
  异步视图内 RefreshToken.for_user 全部 sync_to_async 包裹(修 SynchronousOnlyOperation 500),
  WS ChatConsumer 优先读 Cookie token
- P2 #11 限流: utils/rate_limit.py 固定窗口频控,
  shorturl 生成 匿名10次/分+登录60次/分, 邮箱验证码 同邮箱60s1次+同IP10次/10min,
  登录/注册验证码 错5次作废+成功即销毁防重放, 换绑邮箱/手机 同步落地,
  urls.py 补挂 shorturl 路由(此前 404)
This commit is contained in:
2026-09-08 11:28:00 +08:00
parent 2944b19e6f
commit 3618323192
22 changed files with 711 additions and 37 deletions
+8
View File
@@ -16,6 +16,8 @@ from .views.tasks import (
)
from .views.email import SendChangeEmailCodeAPIView, ChangeEmailAPIView
from .views.phone import SendPhoneCodeAPIView, ChangePhoneAPIView
from .views.favorites import MyFavoritesView, FavoriteToggleView
from .views.token import CookieTokenRefreshView, UserLogoutAPIView
from .views.captcha import CaptchaAPIView
from .views.slider_captcha import SliderCaptchaGenerateView, SliderCaptchaVerifyView
from .views.blacklist import BlacklistListAPIView, BlacklistAddAPIView, BlacklistRemoveAPIView, BlacklistCheckAPIView
@@ -83,6 +85,12 @@ urlpatterns = [
path('tasks/claim/<int:task_id>/', TaskClaimAPIView.as_view(), name='task_claim'),
path('level/', UserLevelAPIView.as_view(), name='user_level'),
path('favorites/', MyFavoritesView.as_view(), name='my_favorites'),
# 修复:新增统一收藏切换端点(Android FavoritesApi.toggleFavorite 依赖此路由)
path('favorites/toggle/', FavoriteToggleView.as_view(), name='my_favorites_toggle'),
# 修复:挂载 JWT 刷新端点(支持 HttpOnly Cookie 与 Bearer 刷新)
path('token/refresh/', CookieTokenRefreshView.as_view(), name='token_refresh'),
# 修复:挂载用户登出端点(清除 HttpOnly Cookie)
path('logout/', UserLogoutAPIView.as_view(), name='user_logout'),
path('regions/', RegionListView.as_view(), name='region_list'),
path('qr-token/', QRTokenView.as_view(), name='qr_token'),
path('qr-status/<str:token>/', QRStatusView.as_view(), name='qr_status'),