feat(user): 用户认证模块——注册/登录/JWT/验证码/限流 - #149
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
There was a problem hiding this comment.
Three concrete regressions stood out: app startup now imports routers that are not present in the tree, the rate-limit middleware trusts a client-supplied forwarded-for header, and the compose defaults give Postgres and the backend different passwords.
- Add backend/Dockerfile with multi-stage build (uv + Python 3.12) - Add docker-compose.yml with backend and PostgreSQL services - Add db/init.sql for automatic database table initialization - Add .env.example with configuration template - PostgreSQL configured with port 7856 and secure password
…browser 三处让部署跑不起来的问题,都在这台服务器上实测定位: 1. 构建阶段 uv sync 超时。宿主机访问 pypi.org 需 8s,构建容器内默认超时会在 下载大包(uvloop)时 "operation timed out" 直接失败。改走国内镜像源并把 UV_HTTP_TIMEOUT 拉到 180s。 2. 容器起来即反复重启,报 "exec /app/.venv/bin/uvicorn: no such file or directory"。 文件其实存在,报的是它 shebang 指向的解释器——uv 装出来的 venv 里 shebang 与 .pth 都是绝对路径,builder 在 /build、runtime 在 /app,跨路径拷贝后解释器与 workspace 包全部失效。把 builder 的 WORKDIR 也改成 /app 即可。 3. 七牛上传 TLS 握手超时、媒体上传请求挂死。宿主机网卡 MTU 1480,而 compose 自建网络不继承 daemon 的 mtu 设置、默认仍是 1500,大包被丢。显式给网络设 1450 后,up-z0.qiniup.com 从握手超时 14s 变为 1.0s,上传恢复正常。 4. 浏览器跨域被全部拦下:OPTIONS 预检返回 405、响应无 access-control-* 头, 后端日志里连请求都看不到。挂上 CORSMiddleware,允许来源用 WINDUP_CORS_ORIGINS 覆盖,并放行 Vercel 预览域名。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…imiting - 注册/登录(邮箱+验证码+密码)、免密登录、刷新 token、登出、改密 - JWT 鉴权中间件(白名单放行 + request.state.current_user 注入) - 邮箱验证码(Redis 存储 + 冷却计时) - 接口限流中间件(Redis 滑动窗口 + 降级策略) - Redis 连接配置与客户端单例 - 22 个集成测试覆盖完整认证链路
- Add auth_client fixture with valid JWT token - Update test_project_api.py to use auth_client - Fix CI failures caused by auth middleware blocking unauthenticated requests
- Remove non-existent imports (orchestrator, character_router, project_router) - Import all ORM models (User, Project, Character) for Base.metadata discovery - Add Base.metadata.create_all(engine) in lifespan startup - Register AuthMiddleware and RateLimitMiddleware - Keep upstream CORS improvements (_cors_origin_regex)
- decode_token throws BizException on expired/invalid tokens - Middleware layer is higher than ExceptionMiddleware, so uncaught BizException results in 500 instead of business code 401 - Wrap decode_token in try/except, route to _biz_error helper - Add test_auth_middleware.py: expired, invalid signature, missing header, malformed header, valid token, whitelist path (6 cases)
- PATCH /auth/profile: update nickname (max 50 chars), returns updated user - POST /auth/reset-password: email + code (purpose=reset_password) + new password, revokes all refresh tokens on success, added to sensitive rate limit paths - Login flow: remove verification code requirement, add per-account rate limiting (5 wrong attempts in 15 min triggers lockout, unified error message for anti-enumeration) - Add ResetPasswordInput, UpdateNicknameInput to user model - Add _check_login_lock, _record_login_failure, _clear_login_failures to service - Tests: nickname update (3), reset password (3), login rate limiting (4), total 10 new cases
xiaocheny214
force-pushed
the
feat/user-auth
branch
from
August 7, 2026 07:31
401cd92 to
6c8cf58
Compare
Clients can spoof X-Forwarded-For to bypass per-IP rate limits. Only honor this header when request comes from a trusted proxy (localhost or Docker network 172.16.0.0/12), otherwise fall back to request.client.host.
xiaocheny214
requested review from
johnnyzhang-eng,
minorcell,
nighca and
xyh202131
August 7, 2026 07:43
huyanxius
approved these changes
Aug 7, 2026
nighca
approved these changes
Aug 7, 2026
| def send_verification_code(self, to: str, code: str) -> None: | ||
| """发送 6 位数字验证码邮件。""" | ||
| try: | ||
| resend.Emails.send( |
Contributor
There was a problem hiding this comment.
Nit: framework/ 的定位怪怪的,从名字看应该是存放于这个 application 业务无关的“框架层”的内容,但是实际上又包含了很多这个 application 特有的逻辑,比如这里的 verification_code email 内容、config 的形状等
This was referenced Aug 7, 2026
huyanxius
added a commit
that referenced
this pull request
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
完整的用户认证体系:注册、登录、JWT 鉴权、邮箱验证码、接口限流。
包含内容
用户服务(server/user)
中间件(web/middleware)
AuthMiddleware:JWT 鉴权,白名单放行,注入request.state.current_user,token 过期/无效返回业务码 401RateLimitMiddleware:Redis 滑动窗口限流,降级策略,仅信任可信代理的 X-Forwarded-For基础设施(framework)
启动与部署
测试
test_user_service.py:35 用例(注册、登录、验证码、token、改密、昵称修改、密码重置、登录限流)test_auth_middleware.py:6 用例(token 过期、签名无效、缺失 header、格式错误、有效 token、白名单)test_project_api.py:9 用例(待 project router 实现后启用)test_smoke.py:1 用例关联