authentication
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseResources
资源
scripts/
auth-checklist.sh
references/
decision-tree.mdscripts/
auth-checklist.sh
references/
decision-tree.mdAuthentication Implementation Workflow
认证功能实现工作流
This skill orchestrates complete authentication implementation from discovery through testing. It replaces library-specific skills (clerk, nextauth, lucia, auth0, firebase-auth, supabase-auth, passport) with a unified workflow that adapts to your stack.
该技能可协调从需求调研到测试的完整认证功能实现流程。它替代了特定库的技能(clerk、nextauth、lucia、auth0、firebase-auth、supabase-auth、passport),提供一个可适配你技术栈的统一工作流。
When to Use This Skill
何时使用该技能
Use when implementing:
- User login and sign-up flows
- Session management (cookies, JWT, server-side sessions)
- OAuth integration (Google, GitHub, etc.)
- Protected routes and API endpoints
- Middleware-based authentication
- Role-based access control (RBAC)
- Token refresh mechanisms
- Password reset flows
在实现以下功能时使用:
- 用户登录与注册流程
- 会话管理(Cookie、JWT、服务器端会话)
- OAuth集成(Google、GitHub等)
- 受保护路由与API端点
- 基于中间件的认证
- 基于角色的访问控制(RBAC)
- 令牌刷新机制
- 密码重置流程
Prerequisites
前置条件
Before starting:
- Understand project framework (Next.js, Remix, Express, etc.)
- Have database schema planned (if using database-backed auth)
- Know authentication approach (managed service vs self-hosted)
- Access to environment variable configuration
开始前需满足:
- 了解项目框架(Next.js、Remix、Express等)
- 已规划数据库 schema(若使用数据库存储认证信息)
- 确定认证方案(托管服务 vs 自部署)
- 可配置环境变量
Workflow Steps
工作流步骤
Step 1: Discovery
步骤1:需求调研
Use to understand existing authentication patterns:
discoveryaml
discover:
queries:
- id: existing-auth
type: grep
pattern: "(useAuth|getSession|withAuth|requireAuth|protect|authenticate)"
glob: "**/*.{ts,tsx,js,jsx}"
- id: middleware-files
type: glob
patterns:
- "**/middleware.{ts,js}"
- "**/auth/**/*.{ts,js}"
- "**/_middleware.{ts,js}"
- id: session-handling
type: grep
pattern: "(session|jwt|token|cookie)"
glob: "**/*.{ts,tsx,js,jsx}"
- id: protected-routes
type: grep
pattern: "(protected|private|requireAuth|withAuth)"
glob: "**/*.{ts,tsx,js,jsx}"
verbosity: files_onlyWhat to look for:
- Existing auth hooks, utilities, or middleware
- Session storage mechanism (cookies, localStorage, server-side)
- Protected route patterns
- Auth provider setup (if using third-party)
Decision Point: If auth is already partially implemented, read existing files to understand the pattern before extending it.
使用工具了解现有认证模式:
discoveryaml
discover:
queries:
- id: existing-auth
type: grep
pattern: "(useAuth|getSession|withAuth|requireAuth|protect|authenticate)"
glob: "**/*.{ts,tsx,js,jsx}"
- id: middleware-files
type: glob
patterns:
- "**/middleware.{ts,js}"
- "**/auth/**/*.{ts,js}"
- "**/_middleware.{ts,js}"
- id: session-handling
type: grep
pattern: "(session|jwt|token|cookie)"
glob: "**/*.{ts,tsx,js,jsx}"
- id: protected-routes
type: grep
pattern: "(protected|private|requireAuth|withAuth)"
glob: "**/*.{ts,tsx,js,jsx}"
verbosity: files_only调研重点:
- 现有认证钩子、工具函数或中间件
- 会话存储机制(Cookie、localStorage、服务器端)
- 受保护路由模式
- 认证服务提供商配置(若使用第三方服务)
决策点: 若已部分实现认证功能,需先阅读现有代码理解其模式,再进行扩展。
Step 2: Detect Stack
步骤2:检测技术栈
Use to determine framework and identify auth approach:
detect_stackyaml
detect_stack:
path: "."Framework Detection:
- Next.js (App Router): Use middleware.ts + Server Actions + cookies
- Next.js (Pages Router): Use getServerSideProps + API routes + NextAuth
- Remix: Use loader/action auth + session cookies
- Express/Fastify: Use middleware + session store
- tRPC: Use context + middleware
- GraphQL: Use context + directives
Consult Decision Tree: Read to choose between managed (Clerk, Auth0), self-hosted (NextAuth, Lucia), or serverless (Supabase Auth) based on framework and requirements.
references/decision-tree.md使用工具确定框架并选择认证方案:
detect_stackyaml
detect_stack:
path: "."框架检测与对应方案:
- Next.js (App Router):使用middleware.ts + Server Actions + Cookie
- Next.js (Pages Router):使用getServerSideProps + API路由 + NextAuth
- Remix:使用loader/action认证 + 会话Cookie
- Express/Fastify:使用中间件 + 会话存储
- tRPC:使用上下文 + 中间件
- GraphQL:使用上下文 + 指令
参考决策树: 阅读,根据框架与需求选择托管服务(Clerk、Auth0)、自部署(NextAuth、Lucia)或无服务器方案(Supabase Auth)。
references/decision-tree.mdStep 3: Implementation Planning
步骤3:实现规划
Based on framework and decision tree, plan which files to create/modify:
Common Files Needed:
-
Middleware (,
middleware.ts)auth.middleware.ts- Intercept requests
- Verify authentication status
- Redirect unauthenticated users
-
Auth Utilities (,
lib/auth.ts)utils/auth.ts- Session creation/validation
- Token generation/verification
- Password hashing (bcrypt, argon2)
-
Auth API Routes (,
/api/auth/login,/api/auth/signup)/api/auth/logout- Handle authentication requests
- Set session cookies
- Return auth state
-
Protected Route Wrappers (,
withAuth)requireAuth- HOCs or server utilities
- Check auth before rendering
- Redirect or return 401
-
Client Hooks (,
useAuth)useSession- Access current user
- Manage client-side auth state
- Trigger login/logout
Framework-Specific Patterns:
Next.js App Router:
typescript
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('session')?.value;
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*']
};Remix:
typescript
// app/utils/session.server.ts
import { createCookieSessionStorage } from '@remix-run/node';
const { getSession, commitSession, destroySession } =
createCookieSessionStorage({
cookie: {
name: '__session',
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secrets: [process.env.SESSION_SECRET],
sameSite: 'lax'
}
});
export { getSession, commitSession, destroySession };Express:
typescript
// middleware/auth.ts
import jwt from 'jsonwebtoken';
import type { Request, Response, NextFunction } from 'express';
export function requireAuth(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace(/^bearer\s+/i, '');
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!);
req.user = payload;
next();
} catch (err) {
return res.status(401).json({ error: 'Invalid token' });
}
}根据框架与决策树,规划需创建/修改的文件:
通用所需文件:
-
中间件 (,
middleware.ts)auth.middleware.ts- 拦截请求
- 验证认证状态
- 重定向未认证用户
-
认证工具函数 (,
lib/auth.ts)utils/auth.ts- 会话创建/验证
- 令牌生成/验证
- 密码哈希(bcrypt、argon2)
-
认证API路由 (,
/api/auth/login,/api/auth/signup)/api/auth/logout- 处理认证请求
- 设置会话Cookie
- 返回认证状态
-
受保护路由包装器 (,
withAuth)requireAuth- 高阶组件或服务器工具函数
- 渲染前检查认证状态
- 重定向或返回401状态码
-
客户端钩子 (,
useAuth)useSession- 获取当前用户信息
- 管理客户端认证状态
- 触发登录/登出操作
框架特定模式:
Next.js App Router:
typescript
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('session')?.value;
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*']
};Remix:
typescript
// app/utils/session.server.ts
import { createCookieSessionStorage } from '@remix-run/node';
const { getSession, commitSession, destroySession } =
createCookieSessionStorage({
cookie: {
name: '__session',
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secrets: [process.env.SESSION_SECRET],
sameSite: 'lax'
}
});
export { getSession, commitSession, destroySession };Express:
typescript
// middleware/auth.ts
import jwt from 'jsonwebtoken';
import type { Request, Response, NextFunction } from 'express';
export function requireAuth(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace(/^bearer\s+/i, '');
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!);
req.user = payload;
next();
} catch (err) {
return res.status(401).json({ error: 'Invalid token' });
}
}Step 4: Write Configuration and Core Files
步骤4:编写配置与核心文件
Use in batch mode to create auth infrastructure:
precision_writeyaml
precision_write:
files:
- path: "middleware.ts"
content: |
# Framework-specific middleware (see patterns above)
- path: "lib/auth.ts"
content: |
# Session validation, token generation
- path: "app/api/auth/login/route.ts"
content: |
# Login endpoint implementation
- path: "app/api/auth/signup/route.ts"
content: |
# Sign-up endpoint with validation
- path: "app/api/auth/logout/route.ts"
content: |
# Logout and session cleanup
verbosity: minimalCRITICAL: No Placeholders
- Implement full validation (zod, yup, etc.)
- Include proper error handling
- Hash passwords with bcrypt/argon2
- Use secure session configuration
- Add CSRF protection where applicable
使用的批量模式创建认证基础设施:
precision_writeyaml
precision_write:
files:
- path: "middleware.ts"
content: |
# 框架特定中间件(参考上述模式)
- path: "lib/auth.ts"
content: |
# 会话验证、令牌生成
- path: "app/api/auth/login/route.ts"
content: |
# 登录端点实现
- path: "app/api/auth/signup/route.ts"
content: |
# 带验证的注册端点
- path: "app/api/auth/logout/route.ts"
content: |
# 登出与会话清理
verbosity: minimal关键要求:禁止使用占位符
- 实现完整验证(zod、yup等)
- 包含完善的错误处理
- 使用bcrypt/argon2进行密码哈希
- 配置安全的会话参数
- 按需添加CSRF防护
Step 5: Install Dependencies
步骤5:安装依赖
Use to install required packages:
precision_execyaml
precision_exec:
commands:
# For JWT-based auth
- cmd: "npm install jsonwebtoken bcryptjs"
- cmd: "npm install -D @types/jsonwebtoken @types/bcryptjs"
# For session-based auth
- cmd: "npm install express-session connect-redis"
- cmd: "npm install -D @types/express-session"
# For managed services
- cmd: "npm install @clerk/nextjs" # Clerk
- cmd: "npm install next-auth" # NextAuth
- cmd: "npm install better-auth" # Better Auth (replaces deprecated Lucia)
verbosity: minimalRun Database Migrations (if needed):
yaml
precision_exec:
commands:
- cmd: "npx prisma migrate dev --name add_user_auth"
timeout_ms: 60000
- cmd: "npx prisma generate"
verbosity: standard使用安装所需包:
precision_execyaml
precision_exec:
commands:
# 基于JWT的认证
- cmd: "npm install jsonwebtoken bcryptjs"
- cmd: "npm install -D @types/jsonwebtoken @types/bcryptjs"
# 基于会话的认证
- cmd: "npm install express-session connect-redis"
- cmd: "npm install -D @types/express-session"
# 托管服务
- cmd: "npm install @clerk/nextjs" # Clerk
- cmd: "npm install next-auth" # NextAuth
- cmd: "npm install better-auth" # Better Auth(替代已废弃的Lucia)
verbosity: minimal运行数据库迁移(若需):
yaml
precision_exec:
commands:
- cmd: "npx prisma migrate dev --name add_user_auth"
timeout_ms: 60000
- cmd: "npx prisma generate"
verbosity: standardStep 6: Security Verification
步骤6:安全验证
Use analysis-engine tools to verify security:
1. Scan for Hardcoded Secrets:
yaml
scan_for_secrets:
paths:
- "lib/auth.ts"
- "app/api/auth/**/*.ts"
- "middleware.ts"Expected Result: Zero secrets found. All API keys, JWT secrets, and credentials must be in files.
.envIf secrets found:
- Move to or
.env.env.local - Use to access
process.env.VAR_NAME - Add to if not already present
.gitignore
2. Audit Environment Variables:
yaml
env_audit:
check_documented: trueExpected Result: All auth-related env vars documented in or README.
.env.exampleRequired Variables (typical):
- or
JWT_SECRETSESSION_SECRET - (if using database)
DATABASE_URL - OAuth credentials (,
GOOGLE_CLIENT_ID, etc.)GITHUB_CLIENT_SECRET - and
NEXTAUTH_URL(for NextAuth)NEXTAUTH_SECRET
3. Validate Implementation:
yaml
undefined使用分析引擎工具验证安全性:
1. 扫描硬编码密钥:
yaml
scan_for_secrets:
paths:
- "lib/auth.ts"
- "app/api/auth/**/*.ts"
- "middleware.ts"预期结果: 未发现任何密钥。所有API密钥、JWT密钥与凭证必须存储在文件中。
.env若发现密钥:
- 移至或
.env.env.local - 使用访问
process.env.VAR_NAME - 若未添加,将其加入
.gitignore
2. 审计环境变量:
yaml
env_audit:
check_documented: true预期结果: 所有认证相关环境变量已在或README中记录。
.env.example典型必填变量:
- 或
JWT_SECRETSESSION_SECRET - (若使用数据库)
DATABASE_URL - OAuth凭证(、
GOOGLE_CLIENT_ID等)GITHUB_CLIENT_SECRET - 与
NEXTAUTH_URL(NextAuth专用)NEXTAUTH_SECRET
3. 验证实现:
yaml
undefinedUse precision_grep to validate critical security patterns
使用precision_grep验证关键安全模式
precision_grep:
queries:
- id: password_hashing
pattern: "bcrypt|argon2|hashPassword"
path: "lib"
glob: "/*.ts"
- id: httpOnly_cookies
pattern: "httpOnly.true|httpOnly:\strue"
path: "."
glob: "/.ts"
- id: csrf_protection
pattern: "csrf|CsrfToken|verifyCsrfToken"
path: "."
glob: "**/.ts"
output:
format: "count_only"
undefinedprecision_grep:
queries:
- id: password_hashing
pattern: "bcrypt|argon2|hashPassword"
path: "lib"
glob: "/*.ts"
- id: httpOnly_cookies
pattern: "httpOnly.true|httpOnly:\strue"
path: "."
glob: "/.ts"
- id: csrf_protection
pattern: "csrf|CsrfToken|verifyCsrfToken"
path: "."
glob: "**/.ts"
output:
format: "count_only"
undefinedStep 7: Protected Routes Implementation
步骤7:实现受保护路由
Create route protection utilities:
Server-Side Protection (Next.js App Router):
typescript
// lib/auth.ts
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
export async function requireAuth() {
const cookieStore = await cookies();
const session = cookieStore.get('session')?.value;
if (!session) {
redirect('/login');
}
const user = await validateSession(session);
if (!user) {
redirect('/login');
}
return user;
}Client-Side Hook (React):
typescript
// hooks/useAuth.ts
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
export function useAuth(options?: { redirectTo?: string }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
useEffect(() => {
fetch('/api/auth/me')
.then(res => res.ok ? res.json() : null)
.then(data => {
if (!data && options?.redirectTo) {
router.push(options.redirectTo);
} else {
setUser(data);
}
})
.finally(() => setLoading(false));
}, [options?.redirectTo, router]);
return { user, loading };
}Apply to Routes:
Use to add auth checks to existing routes:
precision_edityaml
precision_edit:
files:
- path: "app/dashboard/page.tsx"
edits:
- find: "export default function DashboardPage()"
replace: |
export default async function DashboardPage() {
const user = await requireAuth();
hints:
near_line: 1创建路由保护工具:
服务器端保护(Next.js App Router):
typescript
// lib/auth.ts
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
export async function requireAuth() {
const cookieStore = await cookies();
const session = cookieStore.get('session')?.value;
if (!session) {
redirect('/login');
}
const user = await validateSession(session);
if (!user) {
redirect('/login');
}
return user;
}客户端钩子(React):
typescript
// hooks/useAuth.ts
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
export function useAuth(options?: { redirectTo?: string }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
useEffect(() => {
fetch('/api/auth/me')
.then(res => res.ok ? res.json() : null)
.then(data => {
if (!data && options?.redirectTo) {
router.push(options.redirectTo);
} else {
setUser(data);
}
})
.finally(() => setLoading(false));
}, [options?.redirectTo, router]);
return { user, loading };
}应用到路由:
使用为现有路由添加认证检查:
precision_edityaml
precision_edit:
files:
- path: "app/dashboard/page.tsx"
edits:
- find: "export default function DashboardPage()"
replace: |
export default async function DashboardPage() {
const user = await requireAuth();
hints:
near_line: 1Step 8: Test Implementation
步骤8:测试实现
Use to generate auth-specific test scenarios:
suggest_test_casesyaml
suggest_test_cases:
file: "lib/auth.ts"
category: "authentication"Expected Test Cases:
- Valid login with correct credentials
- Login failure with incorrect password
- Sign-up with valid data
- Sign-up with duplicate email
- Protected route redirects unauthenticated users
- Session token refresh
- Logout clears session
- CSRF token validation
- Password reset flow
Run Validation Script:
bash
bash scripts/auth-checklist.sh .Expected Exit Code: 0 (all checks pass)
Manual Testing Checklist:
- Sign up new user
- Verify password is hashed in database
- Log in with credentials
- Access protected route (should succeed)
- Log out
- Access protected route (should redirect to login)
- Test OAuth flow (if implemented)
- Verify session persists across page reloads
- Test token expiration and refresh
使用生成认证特定测试场景:
suggest_test_casesyaml
suggest_test_cases:
file: "lib/auth.ts"
category: "authentication"预期测试用例:
- 正确凭证的有效登录
- 错误密码的登录失败
- 有效数据的注册
- 重复邮箱的注册失败
- 受保护路由重定向未认证用户
- 会话令牌刷新
- 登出清除会话
- CSRF令牌验证
- 密码重置流程
运行验证脚本:
bash
bash scripts/auth-checklist.sh .预期退出码: 0(所有检查通过)
手动测试清单:
- 注册新用户
- 验证数据库中密码已哈希
- 使用凭证登录
- 访问受保护路由(应成功)
- 登出
- 访问受保护路由(应重定向至登录页)
- 测试OAuth流程(若已实现)
- 验证会话在页面刷新后仍保留
- 测试令牌过期与刷新
Common Patterns by Framework
各框架通用模式
Next.js (App Router)
Next.js (App Router)
Session Management:
- Use cookies() from 'next/headers'
- Set httpOnly, secure, sameSite cookies
- Validate in middleware.ts and Server Components
Protected Routes:
- Server-side: await requireAuth() in page/layout
- Client-side: useAuth() hook with redirectTo
- API routes: check cookies in route handlers
OAuth:
- Use NextAuth for simplicity
- Or implement manual OAuth flow with redirect URIs
会话管理:
- 使用中的cookies()
next/headers - 设置httpOnly、secure、sameSite类型的Cookie
- 在middleware.ts与服务器组件中验证
受保护路由:
- 服务器端:在页面/布局中调用
await requireAuth() - 客户端:使用钩子并配置
useAuth()redirectTo - API路由:在路由处理器中检查Cookie
OAuth:
- 为简化流程使用NextAuth
- 或手动实现带重定向URI的OAuth流程
Remix
Remix
Session Management:
- Use createCookieSessionStorage
- Validate in loaders
- Commit session in actions
Protected Routes:
- Check session in loader, throw redirect() if unauthenticated
- Use getSession() utility consistently
OAuth:
- Use remix-auth strategies
- Handle callbacks in dedicated routes
会话管理:
- 使用
createCookieSessionStorage - 在loader中验证
- 在action中提交会话
受保护路由:
- 在loader中检查会话,若未认证则抛出
redirect() - 统一使用工具函数
getSession()
OAuth:
- 使用remix-auth策略
- 在专用路由中处理回调
Express/Fastify
Express/Fastify
Session Management:
- Use express-session + Redis store
- Or JWT tokens in Authorization header
Protected Routes:
- Middleware functions: requireAuth, optionalAuth
- Apply to specific routes or globally
OAuth:
- Use passport.js strategies
- Configure serialize/deserialize user
会话管理:
- 使用express-session + Redis存储
- 或在Authorization头中使用JWT令牌
受保护路由:
- 中间件函数:、
requireAuthoptionalAuth - 应用于特定路由或全局
OAuth:
- 使用passport.js策略
- 配置用户序列化/反序列化
Error Handling
错误处理
Follow error-recovery protocol for auth failures:
遵循认证失败的错误恢复协议:
Login Failures
登录失败
typescript
try {
const user = await validateCredentials(email, password);
await createSession(user.id);
return { success: true };
} catch (err) {
if (err instanceof InvalidCredentialsError) {
// Don't leak whether email exists
return { error: 'Invalid email or password' };
}
if (err instanceof UserLockedError) {
return { error: 'Account locked. Contact support.' };
}
throw err; // Unexpected error
}typescript
try {
const user = await validateCredentials(email, password);
await createSession(user.id);
return { success: true };
} catch (err) {
if (err instanceof InvalidCredentialsError) {
// 不泄露邮箱是否存在
return { error: '邮箱或密码无效' };
}
if (err instanceof UserLockedError) {
return { error: '账户已锁定,请联系支持人员' };
}
throw err; // 意外错误
}Session Validation Failures
会话验证失败
typescript
export async function validateSession(token: string) {
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!);
return await getUserById(payload.userId);
} catch (err) {
if (err instanceof jwt.TokenExpiredError) {
return null; // Let caller handle (refresh or re-login)
}
if (err instanceof jwt.JsonWebTokenError) {
return null; // Invalid token
}
throw err; // Unexpected error
}
}typescript
export async function validateSession(token: string) {
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!);
return await getUserById(payload.userId);
} catch (err) {
if (err instanceof jwt.TokenExpiredError) {
return null; // 由调用方处理(刷新或重新登录)
}
if (err instanceof jwt.JsonWebTokenError) {
return null; // 无效令牌
}
throw err; // 意外错误
}
}Database Errors
数据库错误
typescript
try {
const user = await db.user.create({
data: { email, passwordHash }
});
} catch (err) {
if (err.code === 'P2002') {
// Prisma unique constraint violation
return { error: 'Email already registered' };
}
throw err;
}typescript
try {
const user = await db.user.create({
data: { email, passwordHash }
});
} catch (err) {
if (err.code === 'P2002') {
// Prisma唯一约束冲突
return { error: '该邮箱已注册' };
}
throw err;
}Security Checklist
安全检查清单
Before marking implementation complete:
- Passwords hashed with bcrypt (cost 10+) or argon2
- Session tokens are random (crypto.randomBytes) or signed JWT
- Cookies are httpOnly, secure (in prod), sameSite: 'lax' or 'strict'
- CSRF protection enabled (for cookie-based auth)
- Rate limiting on login/signup endpoints
- Input validation on all auth endpoints
- No sensitive data in error messages
- Environment variables documented in .env.example
- No hardcoded secrets in source code
- Session expiration configured (1-7 days typical)
- Logout clears all auth tokens/sessions
- OAuth redirect URIs whitelisted
标记实现完成前需确认:
- 密码使用bcrypt(cost≥10)或argon2哈希
- 会话令牌为随机值(crypto.randomBytes生成)或签名JWT
- Cookie配置为httpOnly、生产环境下secure、sameSite为'lax'或'strict'
- 启用CSRF防护(基于Cookie的认证需开启)
- 登录/注册端点配置请求频率限制
- 所有认证端点实现输入验证
- 错误消息不包含敏感数据
- 环境变量已在.env.example中记录
- 源代码中无硬编码密钥
- 配置会话过期时间(通常1-7天)
- 登出清除所有认证令牌/会话
- OAuth重定向URI已加入白名单
References
参考资料
- - Managed vs self-hosted vs serverless comparison
references/decision-tree.md - - Project-specific auth patterns
.goodvibes/memory/patterns.json - - Automated validation script
scripts/auth-checklist.sh
- - 托管 vs 自部署 vs 无服务器方案对比
references/decision-tree.md - - 项目特定认证模式
.goodvibes/memory/patterns.json - - 自动化验证脚本
scripts/auth-checklist.sh
Troubleshooting
故障排除
"Session not persisting across requests"
"会话在请求间不持久"
Likely Causes:
- Cookie not being set (check response headers)
- httpOnly preventing client-side access (expected)
- sameSite: 'strict' blocking cross-origin (use 'lax')
- Cookie domain mismatch
Fix:
- Check cookie configuration in auth code
- Verify cookies are in response:
precision_exec: { cmd: "curl -v localhost:3000/api/auth/login" } - Ensure middleware reads cookies correctly
可能原因:
- Cookie未设置(检查响应头)
- httpOnly限制客户端访问(预期行为)
- sameSite:'strict'阻止跨域请求(改用'lax')
- Cookie域名不匹配
修复方案:
- 检查认证代码中的Cookie配置
- 验证响应中是否包含Cookie:
precision_exec: { cmd: "curl -v localhost:3000/api/auth/login" } - 确保中间件正确读取Cookie
"JWT token invalid after server restart"
"服务器重启后JWT令牌无效"
Likely Causes:
- JWT_SECRET changes between restarts
- Secret not in .env file
- Different secret in different environments
Fix:
- Move JWT_SECRET to .env:
JWT_SECRET=<random-256-bit-hex> - Generate with:
openssl rand -hex 32 - Never commit .env to git
可能原因:
- 重启后JWT_SECRET变更
- 密钥未存储在.env文件中
- 不同环境使用不同密钥
修复方案:
- 将JWT_SECRET移至.env:
JWT_SECRET=<随机256位十六进制字符串> - 使用以下命令生成:
openssl rand -hex 32 - 切勿将.env提交至Git
"OAuth callback fails with redirect_uri_mismatch"
"OAuth回调失败,提示redirect_uri_mismatch"
Likely Causes:
- Callback URL not whitelisted in OAuth provider dashboard
- http vs https mismatch
- Port number missing
Fix:
- Check OAuth provider settings
- Add callback URL exactly as it appears in error
- For local dev, use http://localhost:3000/api/auth/callback/google (example)
可能原因:
- 回调URL未在OAuth提供商控制台加入白名单
- http与https不匹配
- 缺少端口号
修复方案:
- 检查OAuth提供商设置
- 完全按照错误信息添加回调URL
- 本地开发示例:
http://localhost:3000/api/auth/callback/google
"Protected routes not redirecting"
"受保护路由未重定向"
Likely Causes:
- Middleware not configured correctly
- Matcher pattern doesn't match route
- Session validation failing silently
Fix:
- Check middleware.ts config.matcher
- Add logging to middleware to verify it's running
- Test session validation independently
可能原因:
- 中间件配置错误
- 匹配器模式与路由不匹配
- 会话验证静默失败
修复方案:
- 检查middleware.ts中的config.matcher
- 在中间件中添加日志以验证其运行状态
- 独立测试会话验证功能
Next Steps After Implementation
实现完成后的下一步
-
Add role-based access control (RBAC):
- Add field to User model
role - Create permission checking utilities
- Protect admin routes
- Add
-
Implement password reset:
- Generate reset tokens
- Send email with reset link
- Validate token and update password
-
Add email verification:
- Generate verification tokens on signup
- Send verification email
- Verify token and mark user as verified
-
Set up refresh tokens:
- Issue short-lived access tokens (15 min)
- Issue long-lived refresh tokens (7 days)
- Rotate refresh tokens on use
-
Add audit logging:
- Log all login attempts (success and failure)
- Track IP addresses and user agents
- Monitor for suspicious activity
-
添加基于角色的访问控制(RBAC):
- 为用户模型添加字段
role - 创建权限检查工具函数
- 保护管理员路由
- 为用户模型添加
-
实现密码重置:
- 生成重置令牌
- 发送带重置链接的邮件
- 验证令牌并更新密码
-
添加邮箱验证:
- 注册时生成验证令牌
- 发送验证邮件
- 验证令牌并标记用户为已验证
-
设置刷新令牌:
- 签发短期访问令牌(15分钟)
- 签发长期刷新令牌(7天)
- 使用时轮换刷新令牌
-
添加审计日志:
- 记录所有登录尝试(成功与失败)
- 跟踪IP地址与用户代理
- 监控可疑活动
Summary
总结
This workflow provides:
- Framework-agnostic authentication implementation
- Security-first approach with validation
- Integration with GoodVibes precision tools
- Automated verification via scripts
- Error handling and troubleshooting
Follow each step sequentially, using precision tools for all file operations and validation.
该工作流提供:
- 框架无关的认证功能实现
- 安全优先的实现与验证
- 与GoodVibes精准工具的集成
- 脚本化的自动化验证
- 错误处理与故障排除指南
按顺序执行每个步骤,所有文件操作与验证均使用精准工具。