跳转到正文

实战案例:独立开发者构建 Authentication 功能

一个独立开发者可以构建完整、安全、测试覆盖充分的 authentication 功能——仅通过遵循 Superpowers 工作流程。


背景

你是一个独立开发者,正在开发一个 Todo App 项目。项目已经有了完整的 CRUD todos、filter、drag-and-drop、dark/light theme 功能——但还没有任何 authentication 系统。任何人打开应用都能看到所有 todos。新的需求是:

  • 添加用户注册(register)
  • 添加登录(login),使用 email + password
  • 保护应用访问(login gate)——未登录则无法进入
  • 为全部功能编写测试

项目还没有 auth 系统。没有人帮你 review 代码。你从头到尾独自工作。

技术栈:

  • React 19 + TypeScript + Vite
  • Tailwind CSS + shadcn/ui
  • localStorage(没有后端)
  • Vitest + Testing Library(测试)
  • Web Crypto API(SHA-256 密码哈希)

你将学到什么

在本教程中,你将应用 Superpowers 的五个核心技能:

  1. Brainstorming & Design -- 先设计再编码
  2. Writing Plans -- 将工作拆分为清晰的任务
  3. TDD -- 先写测试,后实现
  4. 执行与 Subagents -- 并行分派以加速
  5. Debugging & Verification -- 用实际证据验证结果

最终目标:你将拥有一个完整的 authentication 系统,39 个测试用例全部通过,完全按照有纪律的工作流程构建。


分步实践

步骤 1:头脑风暴 Auth 设计

在写任何代码之前,你先进行头脑风暴。你调用 brainstorming skill:

/superpowers:brainstorming "我需要为我的 Todo 项目添加 authentication。在写代码之前先进行头脑风暴。"

AI 先探索代码库,了解当前技术栈(React 19, TypeScript, Vite, Tailwind, shadcn/ui, localStorage),然后逐个提问:

问题 1: "你想要 authentication 做什么?"

  • A) 仅保护应用访问(login gate)-- 数据仍存 localStorage,同一浏览器的每个用户看到相同数据
  • B) 每个用户有独立数据 -- 需要后端/数据库按用户存储 todos
  • C) 仅为学习目的演示 login/register 流程

你选择:A) Login gate -- 仅保护访问,数据保持在 localStorage。

问题 2: "你想用什么登录方式?"

  • A) Email + Password(自建 login/register 表单)
  • B) Social login(Google, GitHub...)-- 使用 Firebase Auth, Supabase Auth, Auth0
  • C) 两者都要

你选择:A) Email + Password -- 自建,不依赖外部服务。

问题 3: "你需要 Register(注册新账户)功能吗?"

  • A) 需要 Register + Login -- 用户创建新账户,存储在 localStorage
  • B) 仅 Login -- 使用 mock/硬编码账户

你选择:A) 需要 Register + Login。

问题 4: "你需要忘记密码功能吗?"

  • A) 需要 -- 显示重置密码表单(mock)
  • B) 不需要 -- 保持简单

你选择:B) 不需要 -- 保持简单,只做 Login + Register。

问题 5: "关于 UI,你想要 Login/Register 页面什么样?"

  • A) 独立页面(全页)-- 未登录时重定向到登录页
  • B) Modal/Dialog -- 在当前应用上显示覆盖层
  • C) 让我来推荐

你选择:A) 独立页面。

收集完足够信息后,AI 展示 3 种方案:

## 方案 A:React Context + localStorage(推荐)
- 创建 AuthContext 管理登录状态
- 用户存储在 localStorage(email + 使用 Web Crypto API 哈希的密码)
- 通过简单的 wrapper 组件实现路由保护
- Login/Register 是全页面,认证后才渲染 App
- 优点:简单,不增加依赖,符合现有架构
- 缺点:没有真正的路由(仅条件渲染)

## 方案 B:React Router + Context
- 添加 react-router-dom 实现真正的路由(/login, /register, /)
- 优点:基于 URL 的导航,后续易于扩展页面
- 缺点:为简单应用增加新依赖,过于复杂

## 方案 C:TanStack Router + Context
- React 的类型安全路由
- 优点:类型安全,现代化
- 缺点:对当前范围来说过度设计

## 建议
方案 A。当前项目是单页应用,没有路由。
仅为了 2 个页面(login + app)就添加路由有些多余。
使用 AuthContext 进行条件渲染就足够了,也能保持项目简洁。

你同意方案 A。AI 继续展示各部分的详细设计:

Part 1 -- Architecture & Data Model:

User type:
  - id: string (crypto.randomUUID)
  - email: string
  - passwordHash: string (SHA-256 via Web Crypto API)
  - createdAt: string

AuthContext provides:
  - user: User | null
  - isAuthenticated: boolean
  - isLoading: boolean
  - login(email, password) → success/error
  - register(email, password) → success/error
  - logout()

localStorage keys:
  - todo-app-users — 已注册用户数组
  - todo-app-session — 当前会话的 user ID
  - todo-app-todos — 保持不变(所有用户共享)

Part 2 -- Component Structure:

<StrictMode>
  <AuthProvider>
    <App>
      ├── isLoading = true → Loading indicator
      │
      ├── isAuthenticated = false → <AuthPage>
      │     ├── <LoginForm />
      │     └── <RegisterForm />
      │
      └── isAuthenticated = true → <TodoApp>
            ├── <Header> (+ logout 按钮, 用户 email)
            ├── <FilterBar>
            ├── <TodoInput>
            ├── <TodoList>
            └── <EditTodoDialog>
    </App>
  </AuthProvider>
</StrictMode>

Part 3 -- UI Design: AI 通过 visual companion 在浏览器上直接展示 2 个 mockup:Centered Card vs Split Layout。你选择了 Split Layout -- 屏幕分为两半,左侧品牌展示 + 右侧表单。

Part 4 -- Validation & Error Handling:

  • Register:email 格式、email 重复、密码 6-128 字符、确认密码匹配
  • Login:email/密码不为空,错误时显示 toast error(使用已有的 Sonner)
  • Session:应用挂载时检查,如果 user ID 无效则自动登出

Part 5 -- Testing Strategy: Vitest + Testing Library,为 storage 测试 mock localStorage。

AI 将设计规格写入 docs/superpowers/specs/2026-03-18-authentication-design.md 并运行 3 轮自动 spec 审查 -- 发现 7 个问题(缺少 loading state、缺少 password 最大长度、缺少 stale session 处理等)并在转入计划编写之前全部修复。

Superpowers 提示: 自动 spec 审查是工作流程的重要组成部分。AI 分派一个 code-reviewer agent 在你批准之前审查 spec。这确保了 spec 没有遗漏。详见 Brainstorming


步骤 2:Superpowers 编写详细计划

基于已批准的设计规格,AI 调用 writing-plans skill 并将工作拆分为 8 个任务:

## Plan: Authentication Implementation

### Task 1: Hash Utility
- 文件: src/lib/hash.ts, src/lib/hash.test.ts
- 使用 Web Crypto API 进行 SHA-256 哈希
- Verification: npx vitest run src/lib/hash.test.ts

### Task 2: Auth Storage
- 文件: src/lib/auth-storage.ts, src/lib/auth-storage.test.ts
- localStorage 中的用户 CRUD + 会话管理
- Verification: npx vitest run src/lib/auth-storage.test.ts

### Task 3: Auth Context
- 文件: src/contexts/auth-context.tsx, src/contexts/auth-context.test.tsx
- AuthProvider + useAuth hook
- Login, register, logout, session restore, isLoading, stale session
- Verification: npx vitest run src/contexts/auth-context.test.tsx

### Task 4: Login Form
- 文件: src/components/login-form.tsx, src/components/login-form.test.tsx
- 表单验证, 提交, 错误显示
- Verification: npx vitest run src/components/login-form.test.tsx

### Task 5: Register Form
- 文件: src/components/register-form.tsx, src/components/register-form.test.tsx
- 验证, 重复 email, 密码过长, 提交
- Verification: npx vitest run src/components/register-form.test.tsx

### Task 6: Auth Page
- 文件: src/components/auth-page.tsx
- Split layout 容器, 在 login/register 之间切换
- 不需要单独测试(由 form tests + auth-context tests 覆盖)

### Task 7: Wire Up
- 修改: src/main.tsx, src/App.tsx, src/components/header.tsx
- 用 AuthProvider 包裹 App, 条件渲染, logout 按钮
- Verification: npx tsc --noEmit && npx vitest run

### Task 8: Smoke Test
- 运行完整测试套件 + TypeScript 检查
- Verification: npx tsc --noEmit && npx vitest run

每个任务有具体的文件、具体的验证命令,计划中已经准备好了详细的测试代码。

计划也经过了 2 轮自动审查 -- 发现问题(测试环境中缺少 crypto.subtle polyfill、缺少 stale session 测试用例、缺少 password > 128 字符测试等)并全部修复。

Superpowers 提示: 实际的计划包含每个测试文件和每个实现文件的完整代码,格式为 - [ ] 复选框。详见 Writing Plans

AI 问你:

"计划已完成,共 8 个任务。你想用 Subagent-Driven(并行)还是 Inline Execution(顺序)方式执行?"

你选择:Subagent-Driven -- 分派多个 agent 并行执行以加速。


步骤 3:使用 Subagent-Driven Development 实现

AI 使用 subagent-driven-development skill 执行计划。不是逐个任务顺序执行,AI 分析任务之间的依赖关系并在可能时并行分派。

Batch 1:Task 1 + Task 2(并行)

Task 1(Hash Utility)和 Task 2(Auth Storage)互不依赖,因此被同时分派给 2 个独立的 agent:

Agent任务测试用例结果
Agent 1Hash Utility (hash.ts + hash.test.ts)3 tests:hash 一致性、不同输入 → 不同哈希、返回十六进制字符串3/3 PASS
Agent 2Auth Storage (auth-storage.ts + auth-storage.test.ts)6 tests:get/save users, add user, find by email, session CRUD, user validation6/6 PASS

两个 agent 都完成后,AI 验证测试并提交:

git commit -m "feat: add SHA-256 password hashing utility"
git commit -m "feat: add auth storage with user and session management"

Batch 2:Task 3 + Task 4/5(并行)

Task 3(Auth Context)需要 Task 1+2,但 Task 4(Login Form)和 Task 5(Register Form)只需要 props interface,因此可以并行运行:

Agent任务测试用例结果
Agent 3Auth Context (auth-context.tsx + test)6 tests:initial state, register + auto-login, login after register, session restore, logout, stale session cleanup6/6 PASS
Agent 4Login + Register Forms12 tests:validation, submit, error display, duplicate email, password too long12/12 PASS

验证后提交:

git commit -m "feat: add AuthContext with login, register, session management"
git commit -m "feat: add login and register form components"

Batch 3:Task 6 + Task 7(顺序,inline)

Task 6(Auth Page)和 Task 7(Wire Up)较小且互相依赖,所以 AI 直接实现:

  • 创建 auth-page.tsx -- split layout 容器
  • 修改 main.tsx -- 用 <AuthProvider> 包裹 App
  • 修改 App.tsx -- 条件渲染 AuthPage / TodoApp + loading state
  • 修改 header.tsx -- 添加用户 email + logout 按钮
git commit -m "feat: add AuthPage with split layout"
git commit -m "feat: wire up authentication — AuthProvider, conditional render, header logout"

每个任务的 TDD 流程: 每个 agent 都遵循循环:先写测试(RED)→ 实现最小代码(GREEN)→ 验证测试 PASS → 提交。详见 TDD


步骤 4:Verification -- 全面验证

计划中的所有 8 个任务已完成。现在是 Task 8:Smoke Test -- 运行完整验证。

TypeScript 检查

npx tsc --noEmit
# (No output) — Clean, no errors

完整测试套件

npx vitest run
✓ src/lib/hash.test.ts (3 tests)
✓ src/lib/auth-storage.test.ts (6 tests)
✓ src/contexts/auth-context.test.tsx (6 tests)
✓ src/components/login-form.test.tsx (5 tests)
✓ src/components/register-form.test.tsx (7 tests)
  ... (以及项目的其他测试文件)

Test Files  8 passed
Tests       39 passed

Git Log -- 7 个干净的提交

6b92624 feat: wire up authentication — AuthProvider, conditional render, header logout
37d68f1 feat: add AuthPage with split layout
...     feat: add login and register form components
...     feat: add AuthContext with login, register, session management
...     feat: add auth storage with user and session management
878af65 feat: add SHA-256 password hashing utility
cc6e2f9 initial: todo app before authentication

39/39 测试 PASS。TypeScript 通过。7 个提交。 这是一个有效的声明,因为它基于实际证据。


结果

完成整个流程后,你拥有:

完整的 Authentication 功能:

  • Login 页面 -- 使用 email + password 登录
  • Register 页面 -- 注册新账户,带完整验证
  • Login gate -- 未登录则无法进入应用
  • Logout -- header 上的 logout 按钮,显示用户 email
  • Session 持久化 -- 刷新页面仍保持登录状态

39 个测试用例 100% 通过 覆盖以下场景:

  • 工具层:hash 函数、localStorage CRUD
  • Context 层:login/register 流程、session 恢复、stale session 清理
  • UI 层:表单验证、错误显示、提交处理
  • 边界情况:email 重复、密码过长(>128 字符)、session 无效

新增文件结构:

src/
  contexts/
    auth-context.tsx          ← AuthProvider + useAuth hook
  components/
    auth-page.tsx             ← Split layout 容器
    login-form.tsx            ← 登录表单
    register-form.tsx         ← 注册表单
  lib/
    hash.ts                   ← SHA-256 helper
    auth-storage.ts           ← localStorage 中的用户 CRUD + session

修改的文件:
  src/main.tsx                ← 用 AuthProvider 包裹 App
  src/App.tsx                 ← 条件渲染 auth/todo + loading state
  src/components/header.tsx   ← 添加 email + logout 按钮

关键要点

1. 独立开发者也需要工作流程

当没有人帮你 review 代码时,Superpowers 工作流程就充当"虚拟同事"的角色。头脑风暴迫使你在编码前深思熟虑。TDD 迫使你在实现前先写测试。Verification 迫使你在声明完成之前证明一切正常运行。

没有工作流程,独立开发者容易陷入陷阱:随心所欲地写代码、没有测试、在未验证时就声称"完成了"。

2. 先进行头脑风暴有助于避免过度工程

在头脑风暴步骤中,AI 提出了 React Router 和 TanStack Router。但因为你从一开始就明确了需求(login gate、single-page app、没有后端),你选择了最简单的方案:React Context + localStorage + 条件渲染。

如果没有头脑风暴,许多开发者会自动添加 router、backend、database "以防万一"。结果是花了 3 倍的时间在一个还不需要的功能上。

3. 自动 Spec 审查发现了漏洞

3 轮 Spec 审查发现了 7 个你可能遗漏的问题:缺少 loading state(刷新时闪现 AuthPage)、缺少 password 最大长度(DoS 风险)、缺少 stale session 处理... 这些漏洞在写一行代码之前就被修复了。

4. Subagent-Driven Development 显著加速

AI 不是顺序执行 8 个任务,而是并行分派:Task 1+2 同时进行,Task 3 + Task 4/5 同时进行。借助并行化,总实现时间显著缩短。

5. 详细计划帮你不偏离方向

有 8 个清晰的任务,每个任务在计划中都有现成的代码,你始终知道下一个任务是什么。你永远不需要坐下来思考"接下来做什么"。

对于独立开发者来说,这尤其重要。独自工作时,很容易分心或在项目的不同部分之间跳来跳去。

6. 39 个测试用例是自动"审查者"

每个测试用例都是一个明确的断言。当你修改代码——重构、添加新功能、修复 bug——你能立即知道是否有什么被破坏了。39 个测试在几秒钟内运行完毕。比任何手动测试方式都快。

7. Verification gate 确保不会在未真正完成时声称"完成"

你有多少次说"搞定了"却没有运行测试?AI 有多少次说"已实现完毕"却没有展示输出?

最终的 Smoke test -- TypeScript 通过 + 39/39 测试通过 -- 完全排除了错误声明的可能性。只有当终端中有实际证据时,你才能说"完成"。


独立开发不等于没有纪律。 Superpowers 给你提供了一套连大团队都要尊重的工作流程:编码前先头脑风暴、实施前先计划、实现前先测试、批准前自动审查、声明前先验证。有好的工作流程的一个人总是胜过没有工作流程的一个人——无论经验多少。