Community编程与开发github.com

Breadstick-Crumbs/add-auth

为项目添加邮箱-密码认证(注册、登录、登出、会话、角色、修改密码、忘记/重置密码),使用经过测试的模板而非从头编写。当用户要求为 FastAPI、Next.js 或 Node 后端添加认证、登录、注册、账户、会话、受保护路由或密码重置时使用。

add-auth 是什么?

该技能旨在为开发者快速集成邮箱-密码认证功能,避免重复造轮子。它通过`install.mjs`脚本将位于技能目录上级`templates/`中的预测试认证模板(包含FastAPI、Next.js App Router和Node核心三种)精确复制到用户项目中,然后仅需调整数据库连接、导入路径和UI等边缘部分,无需修改核心安全逻辑。支持FastAPI(SQLModel/SQLAlchemy)、Next.js App Router(Drizzle/Prisma/原始SQL)以及其他Node服务器(Express、Hono、Fastify等)。技能会先检查项目堆栈和现有认证情况,然后复制模板并提示用户配置环境变量(如`AUTH_SECRET`、SMTP设置等),最后运行测试并报告结果。关键安全规则包括:强制使用Argon2/bcrypt哈希、对未知邮箱进行虚拟哈希检查、重置令牌绑定密码哈希、使用httpOnly SameSite=Lax Cookie等。

兼容平台~Claude Code~Codex CLI~Cursor
Part ofNext.js
npx skills add https://github.com/Breadstick-Crumbs/add-auth/tree/HEAD/skills/add-auth

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

add-auth 是做什么的?

将本插件中经过测试的认证模板复制到用户项目中并完成接入。不要从头编写认证代码,也不要修改模板中的安全逻辑;仅调整边缘部分(数据库访问、导入、UI)。

模板位于 <skill-dir>/../../templates/,其中 <skill-dir> 是本技能的基础目录:

  • templates/fastapi/auth/ – FastAPI 包:config.py、security.py、models.py、db.py、deps.py、routes.py、email.py;测试位于 templates/fastapi/tests/test_auth.py。
  • templates/node/lib/auth/core.ts – 无框架核心(哈希、访问令牌和重置令牌、Cookie 选项),附带 core.test.ts。
  • templates/nextjs/ – 基于核心的 Next.js App Router 层:lib/auth/{schema,users,session,email}.ts、app/(auth)/actions.ts、proxy.ts。

1. 复制前检查

找出以下信息,并用一两条语句告知用户:

  • 技术栈:FastAPI(在 pyproject/requirements 中查找 fastapi)、Next.js(在 package.json 中查找 next)或其他 Node 服务器(Express、Hono、Fastify、纯 http)。
  • 数据库层:SQLModel/SQLAlchemy、Drizzle、Prisma 或原始 SQL,以及 session 或 db 对象的位置。
  • 现有认证:users 表、登录路由、JWT 库、认证提供商(Clerk、Supabase、Auth.js)。如果已有认证,请停止并询问是替换还是扩展。
  • 项目是否已存在包含数据的 users 表。如果是,则通过迁移将模板的列映射到该表,而不是创建第二个表。

2. 复制并接入

使用插件的脚本进行复制,而不是通过读取和重写文件:脚本会精确复制文件且不消耗 token。脚本位于本技能基础目录上两级的 scripts/install.mjs(<skill-dir>/../../scripts/install.mjs)。在项目根目录下先使用 --dry-run 运行,然后正式运行:

node <skill-dir>/../../scripts/install.mjs fastapi app --tests tests   # app/auth/*.py, tests/test_auth.py
node <skill-dir>/../../scripts/install.mjs nextjs .                     # 或者使用 src/(如果 @/ 别名指向该目录)
node <skill-dir>/../../scripts/install.mjs node src/auth                # 仅核心,适用于其他 Node 服务器

如果目标文件已存在,脚本会拒绝覆盖且不复制任何内容。当冲突文件是需要合并的文件(如已有的 proxy.ts 或 middleware.ts)时,使用 --keep-existing 重新运行,该选项会复制其余文件,然后手动合并。只有在用户同意丢失文件的情况下才使用 --force。如果 node 不可用,请手动复制相同的文件(使用 cp),并且仍然不要重新输入它们。

复制后,仅按以下步骤指定的内容进行修改。保持 security.py、core.ts 和路由中的逻辑不变。

FastAPI

  1. 使用 install.mjs fastapi <package-dir> --tests <tests-dir> 复制(例如 app/auth/)。
  2. 编辑 auth/db.py,将 get_session 改为项目现有的 session 依赖项。这是 auth 接触数据库设置的唯一位置。
  3. 如果项目使用纯 SQLAlchemy 而非 SQLModel,将 models.py 中的 User 重写为具有相同列的 SQLAlchemy 模型,并保留 Pydantic 模式。
  4. 在应用主文件中调用 app.include_router(auth_router)。
  5. 使用 user: CurrentUser 或 dependencies=[Depends(require_role("admin"))] 保护路由。
  6. 添加依赖项:pyjwt、pwdlib[argon2,bcrypt]、email-validator、python-multipart、sqlmodel(如果尚未存在)。
  7. 通过项目的迁移系统创建 users 表(如果使用 Alembic,则使用自动生成)。
  8. 修复复制的 test_auth.py 中的导入,指向正确的包路径(例如将 from auth 改为 from app.auth),然后运行测试。

Next.js(App Router)

  1. 使用 install.mjs nextjs <app-root> 复制:核心及其测试、lib/auth/*、app/(auth)/actions.ts 和 proxy.ts。
  2. Next.js 15 或更早版本:将 proxy.ts 重命名为 middleware.ts,并将其导出重命名为 middleware。如果项目已存在中间件/代理文件,则将认证检查合并到其中。
  3. 将 lib/auth/users.ts 指向项目的数据库:修改 db 导入,或为其五个函数重写以适配 Prisma/原始 SQL。将 schema.ts 合并到现有的 Drizzle 模式中并生成迁移。
  4. 将代理中的 PROTECTED 设置为应用的私有路径。
  5. 使用项目自身的组件和样式构建 /sign-in、/sign-up、/forgot-password 和 /reset-password 页面。每个页面都是一个表单,通过 useActionState 将请求提交到对应的服务器动作;在登录页面上将 next 作为隐藏字段传递,在重置页面上传递 token 搜索参数。
  6. 在服务器组件和动作中,使用 lib/auth/session.ts 中的 getUser() 或 requireUser("admin")。
  7. 依赖项:jose、bcryptjs、zod、server-only(如果按原样使用 Drizzle 文件,则还需要 drizzle-orm)。

其他 Node 服务器(Express、Hono、Fastify、纯 http)

仅使用 install.mjs node <dir> 复制核心。以项目风格编写路由,保持与 templates/nextjs/app/(auth)/actions.ts 相同的行为:注册、登录(未知邮箱和错误密码返回相同的错误信息;即使未找到用户也要调用 verifyPassword)、注销、获取当前用户、修改密码、忘记密码(无论账户是否存在都返回相同回复)、重置密码(使用 readResetToken 并传入用户当前的哈希值)。从 session cookie(使用 cookieOptions() 设置)或 Authorization: Bearer 头中读取令牌。添加 requireUser/requireRole 中间件。

3. 环境配置

将以下内容添加到 .env.example(切勿添加到已提交的 .env 中):

  • AUTH_SECRET – 至少 32 个随机字符。使用 node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))" 为用户生成本地 .env 的值;切勿在聊天中打印。
  • AUTH_ACCESS_TOKEN_MINUTES(默认 7 天),AUTH_RESET_TOKEN_MINUTES(默认 60)。
  • FastAPI:FRONTEND_URL,以及用于重置密码邮件的 SMTP_HOST、SMTP_PORT、SMTP_USER、SMTP_PASSWORD、EMAIL_FROM。Next.js:APP_URL,然后将 lib/auth/email.ts 的主体替换为项目的邮件提供商。 如果未配置邮件,重置链接会被记录到日志中,这对于本地开发来说是可以接受的。

4. 检查是否正常运行

运行复制的测试以及项目自身的检查(测试、类型检查、代码检查、构建)。报告失败信息及其输出。然后告知用户他们仍需自行完成的工作,通常包括:在生产环境中设置 AUTH_SECRET、配置邮件、在真实数据库上运行迁移。

规则

  • 保留:Argon2/bcrypt 哈希、针对未知邮箱的虚拟哈希检查、未知账户返回相同回复、重置令牌与密码哈希绑定、令牌的 purpose 检查、httpOnly SameSite=Lax Cookie、重定向时的 safeNext。
  • 不要将令牌存储在 localStorage 中,不要记录密码或令牌,不要为认证路由放宽 CORS。
  • 模板中不包含登录频率限制。如果项目已有频率限制器,请将登录和忘记密码路由放在其后;如果没有,请提及此点。
  • 会话是签名令牌,因此注销只会结束当前浏览器中的会话,但复制的令牌在过期前仍然有效。如果用户需要“全局注销”,请添加一个 token_version 列,并在令牌读取器中检查它。

相关技能