Skip to content

feat(user): 用户认证模块——注册/登录/JWT/验证码/限流 - #149

Merged
nighca merged 12 commits into
1024XEngineer:mainfrom
xiaocheny214:feat/user-auth
Aug 7, 2026
Merged

feat(user): 用户认证模块——注册/登录/JWT/验证码/限流#149
nighca merged 12 commits into
1024XEngineer:mainfrom
xiaocheny214:feat/user-auth

Conversation

@xiaocheny214

@xiaocheny214 xiaocheny214 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

概述

完整的用户认证体系:注册、登录、JWT 鉴权、邮箱验证码、接口限流。

包含内容

用户服务(server/user)

  • 邮箱 + 验证码 + 密码注册
  • 邮箱 + 密码登录(免验证码,账号级限流防暴力破解)
  • 邮箱 + 验证码免密登录
  • 刷新 token / 登出 / 改密
  • 修改昵称(PATCH /auth/profile)
  • 邮箱 + 验证码重置密码(POST /auth/reset_password)
  • Redis 存储验证码 + refresh_token

中间件(web/middleware)

  • AuthMiddleware:JWT 鉴权,白名单放行,注入 request.state.current_user,token 过期/无效返回业务码 401
  • RateLimitMiddleware:Redis 滑动窗口限流,降级策略,仅信任可信代理的 X-Forwarded-For

基础设施(framework)

  • Redis 连接配置 + 客户端单例
  • JWT 配置
  • 邮件发送抽象

启动与部署

  • ORM 自动建表(Base.metadata.create_all)

测试

  • 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 用例

关联

@xiaocheny214 xiaocheny214 added the enhancement New feature or request label Aug 6, 2026
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
windup Ignored Ignored Preview Aug 7, 2026 7:42am

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread backend/packages/app/src/windup_app/bootstrap/app.py Outdated
Comment thread backend/packages/app/src/windup_app/web/middleware/ratelimit.py Outdated
Comment thread docker-compose.yml Outdated
xiaocheny214 and others added 9 commits August 7, 2026 14:15
- 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
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.

@nighca nighca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

实现细节太多了,就不细看了

def send_verification_code(self, to: str, code: str) -> None:
"""发送 6 位数字验证码邮件。"""
try:
resend.Emails.send(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: framework/ 的定位怪怪的,从名字看应该是存放于这个 application 业务无关的“框架层”的内容,但是实际上又包含了很多这个 application 特有的逻辑,比如这里的 verification_code email 内容、config 的形状等

@nighca
nighca merged commit 55f742d into 1024XEngineer:main Aug 7, 2026
6 checks passed
huyanxius added a commit that referenced this pull request Aug 7, 2026
#156 已对齐的口径是验证码只保留给注册、免密登录与重设密码,#149 合入的后端 /auth/login 也已经不再接收它。

收窄 login 的入参类型,密码模式跳过验证码校验、不再渲染验证码输入框与发送按钮,提交时只发邮箱和密码。

密码登录现在填账号密码即可完成,与后端接受的请求体一致。
@xiaocheny214
xiaocheny214 deleted the feat/user-auth branch August 14, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

3 participants