freeCodeCamp考试环境深度拆解:JWT认证与防作弊机制是如何实现的(完整指南)

发布时间:2026/9/3 11:26:37
freeCodeCamp考试环境深度拆解:JWT认证与防作弊机制是如何实现的(完整指南) freeCodeCamp考试环境深度拆解JWT认证与防作弊机制是如何实现的完整指南【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCampfreeCodeCamp.org 的开源代码库中除网页课程外还藏着一套专为**桌面考试应用Exam Environment**打造的服务端系统它用 JWT 认证保证只有合法考生能作答又用随机组卷、服务端计时、逐题时间戳和自动审核标记等手段层层防作弊。本文带你完整拆解 api/src/exam-environment/ 下的核心实现看看一套免费在线教育平台的考试系统如何做到既开放又严谨。一、为什么考试系统需要一套独立的认证普通网页课程用 Cookie 里的jwt_access_token完成登录见 api/src/plugins/auth.ts但考试走的是桌面应用需要一种更可控的身份凭证。于是系统设计了两种路由组路由组是否需要令牌校验典型接口开放路由否GET /exam-environment/token-meta受保护路由是请求头携带 JWT生成试卷、提交答案、查询成绩路由注册位置在 api/src/app.ts所有受保护接口在进入前都会先经过authorizeExamEnvironmentToken钩子拦截身份验证逻辑集中在 api/src/plugins/auth.ts。二、JWT 认证流程三步完成身份验证第 1 步请求头携带签名令牌考试应用调用接口时必须在请求头exam-environment-authorization-token中带上一个由服务端签名JWT_SECRET的 JWT。令牌数据库记录定义在 api/prisma/exam-environment.prisma包含用户 ID、过期时间expireAt且一个用户同一时间只有一张有效令牌。第 2 步验签 解码服务端先用jwt.verify校验签名防止任何人伪造令牌解码后取出其中的examEnvironmentAuthorizationToken字段——它只是数据库里令牌记录的 ID真实身份由数据库确认。第 3 步查库实现可吊销关键一步服务端会去数据库查这条令牌记录若查不到已过期或被吊销立即返回 401 拒绝服务auth.ts。这意味着即使 JWT 本身未过期服务端也能随时让它失效——这是比纯无状态 JWT更强的安全设计。 小彩蛋开放接口 token-meta 遇到无效令牌时返回的竟是418 Teapot代码注释写道服务器拒绝用茶壶随机字符串来冲咖啡JWT相当有梗。三、防作弊机制拆解6 道看不见的防线1️⃣ 准入门槛学术诚信承诺 前置课程开考前的checkPrerequisitesutils/exam-environment.ts要求用户必须已接受学术诚信政策isHonest为真且完成所有前置挑战否则返回 403。2️⃣ 随机组卷答案打乱 隐藏正确标记系统维护一个已生成试卷池考生被随机分配一份尽量没被考过的试卷下发给客户端前每道题的选项用 Fisher-Yates 算法逐份打乱顺序数据库里答案带着isCorrect标记但发给用户时会被剥除constructUserExam——客户端根本拿不到标准答案。3️⃣ 服务端计时改系统时钟也没用考试开始时服务端就记录startTime交卷时若startTime 考试总时长已早于当前服务器时间直接 403 拒绝路由文件。计时权完全在服务器端本地改时间无法延长考试。4️⃣ 逐题时间戳答题节奏全程留痕每次答案发生变化服务端都会写入一条submissionTimeuserAttemptToDatabaseAttemptQuestionSets。这些细粒度的时间数据可用于分析10 秒答完 50 题这类异常行为。5️⃣ 提交校验答案必须来自你那份试卷validateAttemptutils/exam-environment.ts逐层核对交上来的题目、答案 ID 必须全部存在于你被分配的那份生成试卷中。一旦校验失败系统自动创建一条Pending状态的人工审核记录ExamEnvironmentExamModeration上报exam.moderation_flagged监控指标在审核完成前禁止重考。6️⃣ 冷却期考完想重考先等等试卷过期后还有retakeTimeInS冷却期冷却期内重考返回 429路由文件若上一次考试还在待审核同样会被 403 拦下。四、考试生命周期从发卷到出分整个流程都在 exam-environment.ts 中完成值得注意的两处工程细节先落库、再发卷创建考试尝试Attempt记录发生在试卷下发之前——即使考生中途断网这次考试行为也不会凭空消失出分在服务端成绩由calculateScore在服务器端计算客户端只负责展示。审核状态机为Pending → Approved / Denied通过后由定时任务把证书对应挑战记入用户档案。五、这些机制真的有效吗看测试怎么说freeCodeCamp 为考试系统配套了完善的自动化测试新手也可以从这里入手验证上述机制认证流程单测api/src/plugins/auth.test.ts考试接口单测api/src/exam-environment/routes/exam-environment.test.ts端到端测试e2e/exam-token.spec.ts、e2e/exam-results.spec.ts、e2e/academic-honesty.spec.ts、e2e/exam-survey.spec.ts接口请求/响应结构则由 TypeBox 模式定义在 api/src/exam-environment/schemas/考试种子数据脚本见 tools/scripts/seed-exams/。六、核心文件速查 模块路径JWT 认证钩子api/src/plugins/auth.ts考试路由与交卷校验api/src/exam-environment/routes/exam-environment.ts组卷/打乱/评分/时间戳api/src/exam-environment/utils/exam-environment.ts数据模型令牌、审核、试卷api/prisma/exam-environment.prisma通用 JWT 工具api/src/utils/tokens.ts总结freeCodeCamp 的考试环境用可吊销的 JWT 数据库双因子确认解决你是谁再用随机组卷、答案去标记化、服务端计时、逐题时间戳、内容校验加人工审核、冷却期六道防线解决你有没有作弊。对于想学习在线考试系统设计的开发者这套代码是一个非常值得精读的免费范本 【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考