借助Harness工程化思维与Cursor聊天工具,分阶段实现Koa2登录系统:先定义API契约与验收方式,再依次初始化项目、实现注册登录会话、受保护路由及轻量自动化验证脚本,通过反馈回流和上下文组织确保工程落地可复现。
先交代项目背景,再设定契约标准,最后逐步落实具体实现。本文并非流于表面的概念讲解,而是一份可直接跟随操作、在每个阶段都能看到实际产出的完整指南。
工程落地究竟如何推进?下面按步骤展开。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
仓库根目录下,将部署一套可运行的 Node.js + Koa 2 轻量服务。该系统至少具备以下核心能力:

| 功能模块 | 验收标准(人工可执行) |
|---|---|
| 用户注册 | POST /register 成功返回 201 状态码与明确 JSON 响应,密码不记录日志、不以明文形式返回(与 implement guide/NOTES-API-CONTRACT.md 保持一致) |
| 用户登录 | POST /login 成功后建立会话机制(httpOnly Cookie + 服务端 session,与 implement guide/NOTES-API-CONTRACT.md 保持一致) |
| 受保护资源访问 | GET /me 未登录状态返回 401;登录成功后返回当前用户标识信息 |
| 退出登录 | POST /logout 清除当前会话 |
| 可复现运行环境 | README.md 明确标注 node 版本、npm install、npm start 及默认端口号 |
| 轻量自动化验证 | 根目录提供 npm test 或 npm run verify(脚本 scripts/verify-flow.sh,详见阶段六)(任选其一),可验证「注册→登录→/me→登出」完整链路 |
Harness 对照说明:此处体现了「任务如何被清晰表达」以及「系统如何验证任务是否真正完成」——先确定契约,再着手编写代码。
harness-login-now-koa2。harness guide/juejin-post-7620226704209592360.mdharness guide/harness-practice-web-article-to-markdown.md.cursor/rules(本指南不强制要求;若希望 Agent 长期遵循「仅使用 Koa2、根目录实现」等约束,可在阶段七补充)。实际操作要点:此步骤的核心在于「上下文如何被有效组织」——先让模型或助手稳定获取 Harness 定义与契约信息,而非一开始就从零口述概念。
对应实践文档中的「意图」环节:包括 API 路径、是否包含登录状态、输出路径、验收方式——需要先将其转化为可检查的明确表述。
Cmd + L(macOS)或 Ctrl + L(Windows)打开 Chat 面板。@,选择 Folder 或 Files,勾选整个仓库根目录(或至少 harness guide 文件夹)。请仅根据我选中的仓库内容,不编写代码。用简体中文输出一份「API 契约草案」到聊天中,包含以下内容:1) POST /register / POST /login / GET /me / POST /logout 的请求体与响应体 JSON 字段约定(其中 register 成功建议返回 HTTP **201**);2) 会话方案固定为 httpOnly Cookie + 服务端 session(明确 Cookie 名称、SameSite、Path);3) 密码存储必须使用 bcrypt(或同等慢哈希算法),禁止明文存储;4) 列出 5 条「验收用 curl 示例」(包含 Cookie 罐 `-c`/`-b`)。要求:每个接口分别写明成功与失败状态下的 HTTP 状态码。
将 /login 成功后的 Set-Cookie 名称固定为 app_session,并在契约中明确 SameSite 与 Path。将失败情况按「用户名已存在 / 凭据错误 / 未登录」分类到不同状态码,或统一返回 401 并说明理由。
内心认可当前版本的「契约草案」即可。建议将定稿内容复制到仓库 implement guide/NOTES-API-CONTRACT.md(可选操作,便于后续熵管理时对照),本指南不强制规定文件名。
Harness 对照说明:此处体现了「反馈如何回流」——通过自然语言迭代契约,相比直接在代码中修改成本更低。
对应实践文档中的「依赖隔离 / 环境即契约」:通过 package.json + lockfile 将运行时环境固定;不将「全局已安装内容」作为隐含前提。
Ctrl+`)。harness guide 的层级)。@ 引用终端当前路径或根目录,粘贴发送:我需要在仓库根目录初始化一个 Node.js 项目用于 Koa2,请给出逐条终端命令(我将复制执行):npm init、安装 koa、koa-router、koa-bodyparser、bcrypt、以及会话方案所需依赖(如 koa-session 及与 Koa 2 配套的 session 存储依赖,由你列出)。请不要跳过任何说明。目标:package.json 位于根目录,入口文件为 src/index.js。
我执行 npm install 时出现报错:<粘贴完整终端输出>。请分类判断是网络问题、权限问题还是 Node 版本不兼容,并给出最小改动的下一步命令。
操作要点:Harness 告诉我们「错误如何被分类、重试、升级」——先归类问题再调整策略(例如更换 nvm 版本、更换 registry、使用 npm ci 等方式)。
package.json 文件,npm start 或 node src/... 包含明确的脚本配置(可先占位)。npm install 执行无错误提示。持久化中间产物 / 可恢复机制:先搭建一个能正常响应 HTTP 请求的 checkpoint,再叠加登录功能。这样可避免一次性修改过多、失败时无法定位具体问题所在。
Cmd + I)或 Agent 模式(以当前 Cursor 版本为准)。下文统称为「实现面板」。harness guide/harness-practice-web-article-to-markdown.md(使用 @ 输入路径快速引用)在仓库根目录按照阶段 0 的契约(若我没有提供 NOTES 文件则以你上次聊天中的契约为准)实现最小 Koa2 服务:- 仅 GET /health 返回 { "ok": true };- 端口从环境变量 PORT 读取,默认值为 3000;- 使用 CommonJS 或 ESM 请与 package.json 保持一致,不要混用;- 暂不实现登录功能,只需确保进程能正常启动。修改完成后告诉我使用哪条命令启动,以及如何通过 curl 进行验证。
请将所有源码文件放置在 src/ 目录下,不要散落在根目录;同时更新 package.json 中的 main/scripts 配置。
curl -sS http://127.0.0.1:3000/health
| 问题现象 | 在 Chat 中发送的内容 |
|---|---|
| 端口被占用 | EADDRINUSE,请将默认端口改为 3001 并同步更新 README |
| ESM 模块报错 | 报错信息:<粘贴>。请统一使用 CommonJS 或统一使用 "type":"module",选择一种方式并修复整个仓库 |
Harness 对照说明:「轻量验收」——一行 curl 命令即可验证管道末端形态是否正确。
「状态如何被保存、恢复、裁剪」:第一版固定使用 data/users.json 存储用户列表。关键在于数据结构化且可清空重新运行(开发阶段)。
@ 引用:src/ 目录下已有文件 + harness guide/juejin-post-7620226704209592360.md 中的「安全边界」部分(提示模型进行运行时校验)。实现用户持久化功能(固定方案,并在 README 中说明路径与限制):使用 data/users.json:启动时读取该文件(若不存在则视为空数组),注册等变更操作时写回磁盘;写入操作需串行化(例如使用单队列)或在 README 中明确「仅限单进程开发,不适用于多实例并发写入同一文件」。实现 POST /register:校验用户名与密码字段;密码使用 bcrypt hash 存储;成功返回 **201**;用户名唯一性冲突返回 409。暂不实现 session,暂不实现 /me,仅完成注册与内部查询函数。每个错误返回 JSON 格式:{ "error": "<机器可读码>", "message": "<人类可读信息>" }。
curl 重复注册同一用户两次,第二次应返回失败。若返回 500,在 Chat 中发送:注册重复用户时返回 500,终端日志如下:<粘贴>。请判断是校验遗漏问题还是写入竞态问题,并给出修复 diff。
Harness 对照说明:「错误可解释」+「安全边界在运行时」——冲突属于业务错误,不应表现为「服务器内部错误」。
对应原文「工具治理」在 HTTP 服务中的类比:认证逻辑集中在 authService / middleware 层,路由层不堆积判断逻辑;Cookie 设置、密钥、过期时间均从环境变量读取。
@ 引用你的 implement guide/NOTES-API-CONTRACT.md(如果有) + src/ 目录。实现 POST /login:- 校验用户存在且 bcrypt.compare 验证通过;- 使用 koa-session(或同等方案),session 中仅存储 userId 与 username,不存储密码;Cookie(如 app_session)设置 httpOnly、SameSite=Lax、Path=/;登录成功返回 { "ok": true, "user": { "id", "username" } };实现 POST /logout:清除服务端 session,并通过 Set-Cookie 使 app_session 失效(与契约保持一致);未登录状态下调用 logout 仍返回 200 幂等响应(若契约如此约定)。
curl -sS -c cookies.txt -b cookies.txt -H 'Content-Type: application/json' -d '{"username":"u1","password":"p1"}' http://127.0.0.1:3000/logincurl -sS -b cookies.txt http://127.0.0.1:3000/me
若 /me 仍返回 401,在 Chat 中发送:
登录后调用 /me 仍返回 401。请求与响应头信息如下:<粘贴 curl -v 输出>。请判断是 Cookie 未正确写入、域名或 Path 不匹配,还是 session 中间件顺序问题,并进行修复。
Harness 对照说明:「反馈如何回流」——通过 -v 参数和真实头部信息驱动问题修复,而非依靠猜测。
「上下文裁剪」:未通过认证的请求不进入业务处理器;统一返回 401 响应体,避免每个路由重复编写相同的判断逻辑。
在实现面板中粘贴:
实现 GET /me:读取当前登录用户信息,返回 { "user": { "id", "username" } };未登录状态返回 401。抽取一个 requireAuth 中间件,确保在 router 中的执行顺序正确(先解析 session,再执行 requireAuth,最后进入业务逻辑)。在 README 中列出中间件执行顺序示意图。
Harness 对照说明:对应八要素中的「上下文组织」——默认减少内部堆栈信息暴露给客户端(生产环境还可添加统一错误处理机制)。
对应实践文档第 8 步:通过文件或命令级别的验收,验证管道末端形态的正确性。后续 API 改版时,只需回到脚本中修改契约即可。
在根目录添加 scripts/verify-flow.sh(bash 脚本),串行执行以下步骤:注册新随机用户 → 登录 → 携带凭证访问 /me → logout → 再次访问 /me 应返回 401。使用 curl 与临时 cookie 文件。脚本失败时通过 set -e 退出并返回非 0 值。在 package.json 中添加 "verify": "bash scripts/verify-flow.sh"。若用户使用 Windows 系统,请额外提供 scripts/verify-flow.ps1 或在 README 中说明使用 Git Bash 运行 sh 脚本。
npm run verify。若执行失败:将完整输出粘贴到 Chat,并 @scripts/verify-flow.sh 引用相关文件。
Harness 对照说明:「系统如何验证任务是否真正完成」——从「我觉得可以」转变为「脚本验证通过」。
原文强调:安全不能仅依赖自觉。实践文档指出,写入范围需明确限定,不可信输入不能使用 eval。登录系统常见的风险点包括:明文密码日志、弱 session 密钥、将 SESSION_KEYS 等密钥提交到 Git 仓库。
在实现面板中:
补充 README.md 内容:列出必需的环境变量(如 SESSION_KEYS)、生成随机密钥的一行命令示例、禁止将 .env 文件提交到版本控制(检查 .gitignore 配置)。代码层面:确保错误日志不输出密码信息;开发环境可打印路由级别的 info 日志,但不要打印 req.body.password。若存在 CORS 需求,第一版仅允许本地调试来源或直接关闭跨域(说明具体理由)。
随后在 Chat 中 @README.md,发送:
以 Harness 八要素各用一句话对照本登录系统:指出我们在哪些环节实现了任务表达、验证、错误分类、状态保存。将输出内容发送到聊天中即可。
将这条输出另存为 HARNESS-SELF-CHECK.md(可选操作,作为后续熵管理时的对照快照)。
Harness 对照说明:「熵管理」——README 与自检表是防止项目知识流失的关键锚点。将每一步操作记录清晰,即使存放半年后重新回顾,也能迅速恢复上下文继续推进。从长远来看,这反而是整个工程中最关键的环节。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述