create-auth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreate Auth
创建认证体系
You are scaffolding authentication (signin + signup) for the user's project.
你将为用户的项目搭建登录(signin)+ 注册(signup)认证功能。
Step 1: Detect Existing Project Context
步骤1:检测现有项目环境
Before asking any questions, scan the user's project to detect their stack:
- Look for framework config files (e.g., ,
next.config.*,package.json,go.mod,Cargo.toml,pyproject.toml,build.gradle*)pom.xml - Look for existing database/ORM setup (e.g., ,
prisma/schema.prisma,drizzle.config.*,alembic/,diesel.toml)ormconfig.* - Look for existing auth code or dependencies
Use what you find to pre-select the best options in the questions below. If the project clearly uses a specific stack, set that as the recommended option.
在发起任何询问前,先扫描用户项目以检测其技术栈:
- 查找框架配置文件(如 、
next.config.*、package.json、go.mod、Cargo.toml、pyproject.toml、build.gradle*)pom.xml - 查找已有的数据库/ORM配置(如 、
prisma/schema.prisma、drizzle.config.*、alembic/、diesel.toml)ormconfig.* - 查找已有的认证代码或依赖
根据检测结果预先选择以下问题中的最佳选项。若项目明确使用特定框架,将其放在首位并标记“(推荐)”。若未检测到框架,使用以下默认选项:
Step 2: Gather Context with Interactive Questions
步骤2:通过交互式问题收集上下文信息
Use the tool to ask the user to make selections. Ask up to 3 questions in a single call so the user can answer everything at once.
AskUserQuestionAskUserQuestion使用 工具让用户进行选择。在单次 调用中最多提出3个问题,以便用户一次性作答。
AskUserQuestionAskUserQuestionQuestion 1: Language/Framework
问题1:语言/框架
Ask "Which language and framework are you using?" with header "Framework".
Pick the top 4 most relevant options based on what you detected in the project. If you detected the framework, put it first and mark it "(Recommended)". If you could not detect it, use these defaults:
- Next.js — "TypeScript, App Router, API routes"
- Express — "TypeScript/JavaScript, minimal and flexible"
- FastAPI — "Python, async-first with type hints"
- Go + Chi — "Go, lightweight and idiomatic"
The user can always pick "Other" to specify a different stack.
询问“你使用的语言和框架是什么?”,标题为“框架”。
根据项目检测结果选择最相关的前4个选项。若已检测到框架,将其放在首位并标记“(推荐)”。默认选项:
- Next.js — "TypeScript、App Router、API 路由"
- Express — "TypeScript/JavaScript、轻量灵活"
- FastAPI — "Python、优先异步、支持类型提示"
- Go + Chi — "Go、轻量且符合语言习惯"
用户也可选择“其他”来指定不同技术栈。
Question 2: Database/ORM
问题2:数据库/ORM
Ask "Which database and ORM/query layer?" with header "Database".
Again, pick the top 4 most relevant options based on the project. If detected, mark it "(Recommended)". Defaults:
- PostgreSQL + Prisma — "Type-safe ORM with migrations (JS/TS)"
- PostgreSQL + Drizzle — "Lightweight TypeScript ORM, SQL-like syntax"
- PostgreSQL + SQLAlchemy — "Full-featured Python ORM"
- SQLite + raw queries — "Simple, no server needed, good for prototyping"
询问“你使用的数据库和ORM/查询层是什么?”,标题为“数据库”。
同样根据项目检测结果选择最相关的前4个选项。若已检测到,标记“(推荐)”。默认选项:
- PostgreSQL + Prisma — "带迁移功能的类型安全ORM(JS/TS)"
- PostgreSQL + Drizzle — "轻量TypeScript ORM、类SQL语法"
- PostgreSQL + SQLAlchemy — "功能完整的Python ORM"
- SQLite + 原生查询 — "简单无需服务器、适合原型开发"
Question 3: Session Strategy
问题3:会话策略
Ask "How should sessions be managed?" with header "Sessions".
- Database sessions (Recommended) — "Server-side sessions stored in your database. More secure — sessions can be revoked instantly"
- JWT tokens — "Stateless tokens signed by the server. Simpler to scale, but harder to revoke"
询问“应如何管理会话?”,标题为“会话管理”。
- 数据库存储会话(推荐) — "服务器端会话存储在数据库中,安全性更高,可立即撤销会话"
- JWT令牌 — "服务器签名的无状态令牌,扩展更简单,但撤销难度大"
Step 3: Ask Which Features to Add
步骤3:询问需添加的功能
After the user answers the stack questions, use again to ask which additional auth features they want. Use multiSelect: true so they can pick multiple features at once.
AskUserQuestion用户回答技术栈问题后,再次使用 询问他们需要的额外认证功能。开启 multiSelect: true 以便用户可同时选择多个功能。
AskUserQuestionQuestion 1: Authentication Methods
问题1:认证方式
Ask "Which authentication methods do you want to add?" with header "Auth methods". Set multiSelect to true.
- Email OTP — "Passwordless sign-in via one-time codes sent to email"
- Magic Link — "Passwordless sign-in via emailed links"
- Phone Number — "SMS-based OTP authentication"
- Passkey — "WebAuthn/FIDO2 passwordless authentication"
询问“你想添加哪些认证方式?”,标题为“认证方式”,开启多选。
- 邮箱OTP — "通过发送至邮箱的一次性验证码实现无密码登录"
- 魔法链接 — "通过邮箱发送的链接实现无密码登录"
- 手机号 — "基于SMS的OTP认证"
- Passkey — "WebAuthn/FIDO2 无密码认证"
Question 2: Security Features
问题2:安全功能
Ask "Which security features do you want?" with header "Security". Set multiSelect to true.
- Two-Factor Auth (Recommended) — "TOTP-based second factor with backup codes"
- Captcha — "Bot protection on sign-up and sign-in (reCAPTCHA, hCaptcha, Turnstile)"
- Password Breach Check — "Check passwords against the Have I Been Pwned database"
- Rate Limiting — "Throttle auth endpoints to prevent brute-force attacks"
询问“你需要哪些安全功能?”,标题为“安全特性”,开启多选。
- 双因素认证(推荐) — "基于TOTP的二次验证,支持备份码"
- 验证码(Captcha) — "注册和登录时的机器人防护(reCAPTCHA、hCaptcha、Turnstile)"
- 密码泄露检测 — "对照Have I Been Pwned数据库检查密码安全性"
- 速率限制 — "限制认证端点请求频率,防止暴力破解"
Question 3: Additional Capabilities
问题3:附加功能
Ask "Any additional capabilities?" with header "Extras". Set multiSelect to true.
- Multi-Session — "Allow multiple concurrent sessions per user"
- Username Auth — "Sign in with username instead of (or in addition to) email"
- Organization / Teams — "Multi-tenant support with roles, invitations, and RBAC"
- API Keys — "Generate API keys for programmatic access"
询问“是否需要附加功能?”,标题为“附加功能”,开启多选。
- 多会话支持 — "允许单个用户同时存在多个会话"
- 用户名认证 — "使用用户名(而非或同时使用邮箱)登录"
- 组织/团队管理 — "多租户支持,包含角色、邀请和RBAC权限控制"
- API密钥 — "生成用于程序化访问的API密钥"
Step 4: Wait for All Answers
步骤4:等待所有回答
Do not write any code until the user has answered all questions. Once you have their selections, proceed to Step 5.
在用户回答所有问题前,请勿编写任何代码。 收到用户的所有选择后,进入步骤5。
Step 5: Generate Auth
步骤5:生成认证代码
Generate the core auth (schema + endpoints below) plus any selected features. For each selected feature, read the matching reference file from to get the schema additions, endpoint specs, and implementation details.
references/features/| Feature | Reference file |
|---|---|
| Email OTP | |
| Magic Link | |
| Phone Number | |
| Passkey | |
| Two-Factor Auth | |
| Captcha | |
| Password Breach | |
| Rate Limiting | |
| Multi-Session | |
| Username Auth | |
| Organization/Teams | |
| API Keys | |
生成核心认证代码(如下述的表结构+端点)以及用户选择的所有附加功能。对于每个选中的功能,从 目录中读取对应的参考文件,获取表结构扩展、端点规范和实现细节。
references/features/| 功能 | 参考文件路径 |
|---|---|
| 邮箱OTP | |
| 魔法链接 | |
| 手机号认证 | |
| Passkey认证 | |
| 双因素认证 | |
| 验证码防护 | |
| 密码泄露检测 | |
| 速率限制 | |
| 多会话支持 | |
| 用户名认证 | |
| 组织/团队管理 | |
| API密钥生成 | |
Core Schema and Endpoints
核心表结构与端点
Generate the following core auth using the schema and endpoint specs below.
Adapt everything to the user's language/framework idioms:
- Naming: (snake_case) in Python/Go/Rust,
email_verified(camelCase) in JS/TS,emailVerified(PascalCase) in C#EmailVerified - Types: use the language's native types (e.g. in C++,
std::stringin Rust/Java,Stringin Go/TS)string - IDs: use idiomatic generation — (Go),
uuid.New()(Rust),Uuid::new_v4()(JS),crypto.randomUUID()(Python),uuid4()(C++), etc.boost::uuids::random_generator() - Password hashing: use the idiomatic library — (Go/JS/Python),
bcrypt(Rust),argon2(C/C++), etc.libsodium - Error handling: use the language's conventions (Result types in Rust, error returns in Go, exceptions in Python/Java, etc.)
- File structure: follow the project's existing layout and conventions
根据以下表结构和端点规范生成核心认证代码。
所有代码需适配用户所选语言/框架的风格:
- 命名规范:Python/Go/Rust使用 (蛇形命名),JS/TS使用
email_verified(驼峰命名),C#使用emailVerified(帕斯卡命名)EmailVerified - 类型:使用语言原生类型(如C++的 、Rust/Java的
std::string、Go/TS的String)string - ID生成:使用语言惯用的生成方式 — Go的 、Rust的
uuid.New()、JS的Uuid::new_v4()、Python的crypto.randomUUID()、C++的uuid4()等boost::uuids::random_generator() - 密码哈希:使用语言生态的标准库 — Go/JS/Python的 、Rust的
bcrypt、C/C++的argon2等libsodium - 错误处理:遵循语言的约定(Rust的Result类型、Go的错误返回、Python/Java的异常、等)
- 文件结构:遵循项目现有的布局和规范
Schema
表结构
Create these tables/models:
User
| Field | Type | Constraints |
|---|---|---|
| id | string | primary key |
| string | unique, not null | |
| name | string | nullable |
| emailVerified | boolean | default false |
| createdAt | datetime | default now |
| updatedAt | datetime | auto-update |
Session
| Field | Type | Constraints |
|---|---|---|
| id | string | primary key |
| userId | string | foreign key -> User, not null |
| token | string | unique, not null |
| expiresAt | datetime | not null |
| createdAt | datetime | default now |
Account
| Field | Type | Constraints |
|---|---|---|
| id | string | primary key |
| userId | string | foreign key -> User, not null |
| providerId | string | not null (e.g. "credential") |
| passwordHash | string | nullable |
| createdAt | datetime | default now |
| updatedAt | datetime | auto-update |
创建以下表/模型:
用户(User)
| 字段 | 类型 | 约束条件 |
|---|---|---|
| id | string | 主键 |
| string | 唯一、非空 | |
| name | string | 可为空 |
| emailVerified | boolean | 默认值 false |
| createdAt | datetime | 默认当前时间 |
| updatedAt | datetime | 自动更新 |
会话(Session)
| 字段 | 类型 | 约束条件 |
|---|---|---|
| id | string | 主键 |
| userId | string | 外键关联User、非空 |
| token | string | 唯一、非空 |
| expiresAt | datetime | 非空 |
| createdAt | datetime | 默认当前时间 |
账户(Account)
| 字段 | 类型 | 约束条件 |
|---|---|---|
| id | string | 主键 |
| userId | string | 外键关联User、非空 |
| providerId | string | 非空(如 "credential") |
| passwordHash | string | 可为空 |
| createdAt | datetime | 默认当前时间 |
| updatedAt | datetime | 自动更新 |
Endpoints
端点
POST /api/auth/sign-up
- Body:
{ email, password, name? } - Validate email format and password length (min 8 chars)
- Hash password with a strong algorithm (bcrypt, argon2, or scrypt — use whichever is idiomatic for the language)
- Create User + Account (providerId: "credential") + Session
- Return session token and user (without password)
- Email enumeration protection: If the email already exists, return the same status and same response shape as a successful sign-up — do not return 409 or any error that reveals the email is taken. The response should be indistinguishable from a real sign-up. Implementation: attempt the insert, catch the unique constraint violation, hash the password anyway (to keep timing consistent), and return a fake success with a dummy user ID and token (that won't actually work as a session). This prevents attackers from discovering which emails are registered via the sign-up endpoint.
200 OK
POST /api/auth/sign-in
- Body:
{ email, password } - Look up user by email, verify password hash
- Create new Session
- Return session token and user (without password)
- Return 401 on invalid credentials (generic message, no user enumeration)
GET /api/auth/session
- Read session token from Authorization header (Bearer) or cookie
- Look up session, verify not expired
- Return user info if valid, 401 if not
POST /api/auth/sign-out
- Read session token
- Delete session from database
- Return 200
POST /api/auth/sign-up
- 请求体:
{ email, password, name? } - 验证邮箱格式和密码长度(最少8位)
- 使用强哈希算法对密码进行哈希处理(bcrypt、argon2或scrypt,选择语言生态的标准算法)
- 创建User + Account(providerId: "credential") + Session
- 返回会话令牌和用户信息(不含密码)
- 防止邮箱枚举攻击:若邮箱已存在,返回与注册成功相同的状态码和响应格式,不得返回409或任何泄露邮箱已注册的错误。实现方式:尝试插入数据,捕获唯一约束冲突,仍对密码进行哈希处理(保持耗时一致),返回一个看似有效但实际无法使用的虚拟用户ID和令牌,使响应与真实注册成功完全一致。
200 OK
POST /api/auth/sign-in
- 请求体:
{ email, password } - 根据邮箱查找用户,验证密码哈希
- 创建新的Session
- 返回会话令牌和用户信息(不含密码)
- 凭证无效时返回401(通用提示,不泄露用户枚举信息)
GET /api/auth/session
- 从Authorization头(Bearer格式)或Cookie中读取会话令牌
- 查找会话并验证未过期
- 有效则返回用户信息,无效则返回401
POST /api/auth/sign-out
- 读取会话令牌
- 从数据库中删除该会话
- 返回200
Implementation Rules
实现规则
- Write all auth code by hand. Do NOT use auth libraries (better-auth, next-auth, Auth.js, lucia, passport, etc.). The only external dependencies allowed are: the web framework itself, the database/ORM layer, and a password hashing library (bcrypt, argon2, scrypt). Everything else — session management, token generation, route handlers — must be written directly. Keep it minimal.
- Use crypto-random IDs for all primary keys and session tokens — use the idiomatic method for the language (,
crypto.randomUUID(),uuid.New(),Uuid::new_v4(), etc.)secrets.token_hex() - Hash passwords with a strong algorithm — use what's standard for the ecosystem (bcrypt, argon2, scrypt, libsodium, etc.)
- Never log or expose password hashes
- Use constant-time comparison for password verification (the hashing library handles this)
- Set session expiry to 7 days by default
- Return generic "Invalid credentials" on sign-in failure — do not reveal whether the email exists
- Prevent email enumeration on sign-up: When a duplicate email is submitted, return the same status code and response shape as a successful sign-up. Always hash the password (even for duplicates) to prevent timing-based detection. Return a plausible but non-functional fake token and user ID so the response is indistinguishable from a real sign-up.
- Follow the project's existing code style, file structure, and patterns
- If the language has a strong type system (Rust, Go, C++, etc.), define proper types/structs for request/response bodies — do not use untyped maps
- 所有认证代码需手动编写,禁止使用认证库(如better-auth、next-auth、Auth.js、lucia、passport等)。仅允许使用以下外部依赖:Web框架本身、数据库/ORM层、密码哈希库(bcrypt、argon2、scrypt)。其他所有功能——会话管理、令牌生成、路由处理——必须手动实现,保持代码极简。
- 所有主键和会话令牌使用加密安全的随机ID生成——使用语言惯用的方法(如、
crypto.randomUUID()、uuid.New()、Uuid::new_v4()等)secrets.token_hex() - 使用强哈希算法处理密码——选择生态标准算法(bcrypt、argon2、scrypt、libsodium等)
- 禁止记录或泄露密码哈希值
- 密码验证使用常量时间比较(哈希库通常已内置该特性)
- 默认会话有效期为7天
- 登录失败时返回通用提示“凭证无效”——不得泄露邮箱是否已注册
- 注册时防止邮箱枚举:提交重复邮箱时,返回与注册成功相同的状态码和响应格式。始终对密码进行哈希处理(即使邮箱重复),防止基于耗时的检测。返回看似合理但无法使用的虚拟令牌和用户ID,使响应与真实注册成功无差异。
- 遵循项目现有的代码风格、文件结构和模式
- 若语言具备强类型系统(Rust、Go、C++等),为请求/响应体定义合适的类型/结构体——禁止使用无类型映射
Step 6: Run the Migration
步骤6:执行数据库迁移
After generating all code, run the database migration automatically so the user doesn't hit "table does not exist" errors. Use the project's existing database driver/connection to execute the migration SQL.
For JS/TS projects using , the tagged-template function cannot run plain SQL strings. Use instead when executing migration statements programmatically.
@neondatabase/serverlesssqlsql.query(statement)生成所有代码后,自动执行数据库迁移,避免用户遇到“表不存在”的错误。使用项目现有的数据库驱动/连接来执行迁移SQL。
对于使用的JS/TS项目,带标签的模板字符串函数无法执行纯SQL字符串。执行迁移语句时请使用替代。
@neondatabase/serverlesssqlsql.query(statement)Common Pitfalls
常见陷阱
Before generating code, read all files in and follow their rules strictly. These are real bugs encountered in production.
references/pitfalls/| Pitfall | Reference file |
|---|---|
| API routes must catch DB errors | |
| Sign-up catch must not re-throw | |
| Auth helpers must not throw | |
| Client must handle non-JSON | |
生成代码前,请仔细阅读目录下的所有文件,并严格遵循其中的规则。这些都是生产环境中实际遇到的Bug。
references/pitfalls/| 陷阱场景 | 参考文件路径 |
|---|---|
| API路由必须捕获数据库错误 | |
| 注册错误捕获后不得重新抛出 | |
| 认证辅助函数不得抛出异常 | |
| 客户端需处理非JSON响应 | |
Reference Implementations
参考实现
Full working examples are in the directory alongside this skill. Use the matching reference as a starting point and adapt to the user's specific setup:
references/| File | Stack |
|---|---|
| Next.js App Router + Drizzle + PostgreSQL |
| Express + Prisma + PostgreSQL |
| Go + Chi + database/sql + PostgreSQL |
| FastAPI + SQLAlchemy + PostgreSQL |
| Rust + Axum + sqlx + PostgreSQL |
| Kotlin + Spring Boot + JPA + PostgreSQL |
If the user's stack doesn't match any reference, use the closest one as a structural guide and adapt idioms accordingly.
完整的可运行示例存放在本技能的目录中。选择与用户技术栈匹配的参考实现作为起点,适配用户的具体配置:
references/| 文件路径 | 技术栈组合 |
|---|---|
| Next.js App Router + Drizzle + PostgreSQL |
| Express + Prisma + PostgreSQL |
| Go + Chi + database/sql + PostgreSQL |
| FastAPI + SQLAlchemy + PostgreSQL |
| Rust + Axum + sqlx + PostgreSQL |
| Kotlin + Spring Boot + JPA + PostgreSQL |
若用户的技术栈与现有参考实现不匹配,选择最接近的实现作为结构参考,并适配目标语言的惯用写法。