未设置标题
WARNING
- 由claude生成
介绍
cap.js 是一款开源的、十分简单的人机校验方案,同时功能也比较完善。
本来也一直想做类似 reCaptcha 的人机校验功能,正好无意中刷到了这个项目,一看仓库作者也是很用心,而且是完全开源的,就决定尝试一下。
后端可以像我一样集成到项目中,也有一个 standalone 的版本。社区也有各种版本,java/go/python 等等,都可以前去尝试。
项目默认是全局的 cap token guard 守卫的,如果有不重要的公共接口就做 cap token free 处理,也就是添加一个 cap token free 的 guard。
相关链接
流程图
mermaid
sequenceDiagram
participant Client as 客户端<br/>(浏览器)
participant Guard as CAP Guard<br/>(WalnutAdminGuardCap)
participant Cache as Redis缓存
participant Lock as MurLock<br/>(分布式锁)
participant CapAPI as CapJS API<br/>(第三方)
participant Challenge as Challenge<br/>State Service
Note over Client,Challenge: 每个请求都会执行 CAP Guard
Client->>Guard: HTTP 请求<br/>(携带 capToken Cookie)
activate Guard
Note over Guard: Step 1: 检查是否跳过
Guard->>Guard: 检查 @WalnutAdminGuardCapFree()<br/>或 Postman 请求
alt 需要跳过验证
Guard-->>Client: 跳过验证,直接通过
end
Note over Guard: Step 2: 读取风险决策
Guard->>Guard: 读取 request.risk.comprehensive<br/>.recommendation
alt 无风险评估数据
Guard-->>Client: 警告并允许通过
end
Note over Guard: Step 3: CAP Token 硬校验
Guard->>Guard: 获取 Cookie 中的 capToken
alt Token 缺失
alt shouldChallenge = true
Guard-->>Client: 40116 Interaction Required<br/>(需要明确交互)
else shouldChallenge = false
Guard-->>Client: 40117 Refresh Required<br/>(无感刷新)
end
end
Note over Guard,Cache: Token 存在,验证有效性
Guard->>Cache: getCapTokenCache(deviceId)
alt 缓存命中
Cache-->>Guard: 返回缓存结果 (true/false)
Guard->>Guard: 快速路径验证通过
else 缓存未命中
Guard->>Lock: 请求分布式锁<br/>Key: CAP:{deviceId}
Lock-->>Guard: 获取锁成功 (3s 超时)
Note over Guard: Double-Check 模式
Guard->>Cache: 再次检查缓存<br/>(防止并发重复验证)
alt Double-Check 缓存命中
Cache-->>Guard: 返回缓存结果
else 缓存仍未命中
Guard->>CapAPI: AppCapJS.validateToken(capToken)
activate CapAPI
CapAPI-->>Guard: { success: true/false }
deactivate CapAPI
alt 验证失败
Guard-->>Client: 40111 You Are Bot<br/>(判定为机器人)
else 验证成功
Guard->>Cache: setCapTokenCache(deviceId)<br/>(缓存验证结果)
Cache-->>Guard: 缓存成功
end
end
Guard->>Lock: 释放分布式锁
end
Note over Guard: Step 4: 标记 Critical Factors
Guard->>Challenge: markChallengeHandled()<br/>批量标记所有 criticalFactors
activate Challenge
Challenge->>Challenge: 根据 userId 自动区分<br/>Pre Auth / Post Auth 因子
Challenge-->>Guard: 标记成功
deactivate Challenge
Guard-->>Client: 验证通过,继续执行业务逻辑
deactivate Guard
Note over Client: 请求进入 Controller 层