Skip to content

鉴权方式

HyperZoneFRP Panel 面向开发者的接口统一使用 JWT 强制鉴权;登录、注册等公开接口无需令牌,已开启两步验证的账户走两段式登录。每个接口在 接口参考 各章均有「鉴权」标注,本章说明校验链的精确行为、错误响应与常见坑。

JWT 强制鉴权

绝大多数用户端接口(/api/users/*/api/nodes/*/api/proxies/*/api/auth/me 等)要求请求携带有效的 JWT,且通过会话双重校验:

Authorization: Bearer <token>

校验链(逐条失败即中止)

  1. 提取令牌:只认 Authorization: Bearer 请求头。JWT 禁止通过 URL Query 传递(避免凭据落入访问日志、代理日志与监控链路),传了也不会被识别。
  2. JWT 校验:签名与有效期验证,失败返回 401「无效的令牌或令牌已过期」。
  3. 会话校验:令牌必须在 Redis 中存在有效会话,失败返回 401「会话无效或已过期,请重新登录」。仅持有未过期 JWT 但会话已被清除(如重新登录、修改密码、管理员踢下线)的请求会被拒绝
  4. 用户状态校验:
    • 账户被封禁 → 403,响应体 data 携带 { "isBanned": true, "ban_reason": "..." };
    • 账户状态非 activeAuthVersion 不匹配(修改密码会递增该版本)→ 401「账户状态或认证版本已变更,请重新登录」。

失败响应形态

json
{
  "code": 401,
  "message": "未提供认证令牌"
}
HTTP 状态场景
401未携带 Authorization 头 / JWT 无效或过期 / 会话无效或过期 / 用户不存在 / AuthVersion 变更
403账户被封禁(data.isBanned=true,含 ban_reason)

会话相关接口

  • GET /api/auth/me — 校验通过后可拿到当前用户完整资料;
  • GET /api/auth/sessions — 列出本人全部会话(含 IP、浏览器、是否当前会话);
  • DELETE /api/auth/sessions/:sessionId — 吊销单个会话;
  • POST /api/auth/sessions/heartbeat — 会话保活;
  • POST /api/auth/logout — 删除当前会话。该接口故意公开:JWT 已过期也能登出,清理本地凭据即可,不必先刷新令牌。

访问密钥签到鉴权(仅 POST /api/users/checkin)

签到是全站唯一支持访问密钥替代 JWT 的接口,供脚本/定时任务免登录自动签到:

X-Access-Key: <访问密钥>
bash
curl -X POST -H 'X-Access-Key: <访问密钥>' \
  'https://api.hyperfrp.com/api/users/checkin'
  • 访问密钥即「安全设置 → 密码与访问密钥」中展示的 32 位小写 hex 字符串,与 frpc 配置内嵌的凭证同源(users.access_key);
  • 凭证只允许走请求头,不接受 URL Query / 请求体传递;
  • 请求同时携带 Authorization: Bearer 时一律按 JWT 校验,校验失败不回退访问密钥——避免会话过期被静默换道掩盖;
  • 无效或格式非法的密钥统一 401「访问密钥无效」;封禁账户 403(data.isBanned=true,与 JWT 封禁同构);非 active 账户 401「账户状态异常,无法使用访问密钥」;
  • 重置访问密钥后旧密钥立即失效:签到脚本与 frpc 配置同时失效,需同步更新;
  • 该替代通道仅对签到开放——/api/users/* 其余接口(改密码、关 2FA 等)只认 JWT,访问密钥不会因此获得会话权限。接口细节见用户章节 · 签到

两步验证(2FA)登录流

开启两步验证的用户,登录接口不会直接返回正式令牌,而是走两段式:

POST /api/auth/login
      │  命中 2FA

{ "requires2FA": true, "tempToken": "..." }   ← 无 JWT


POST /api/auth/2fa/verify  { "tempToken": "...", "code": "123456" }


{ "token": "...", "expiresIn": ..., "user": {...} }   ← 正式 JWT
  • tempToken 短时效、单用途,仅用于换取正式令牌;
  • 未开启 2FA 的用户登录一次即返回 token,不存在 requires2FA 字段(见 认证与会话)。

实践建议

  • 令牌存储与续期:登录响应含 tokenexpiresIn(秒)。长期在线的客户端应定期调用 POST /api/auth/sessions/heartbeat 维持会话;会话失效后所有 Protect 接口统一返回 401,应引导重新登录而非重试。
  • 封禁处理:收到 403 且 data.isBanned=true 时停止重试,向用户展示 ban_reason
  • 排查请求:每个响应都带 X-Request-ID 头(客户端可自带合法值对齐调用链,非法值会被服务端静默替换),报障时提供该 ID 可在服务端结构化日志中精确定位。

本站基于 VitePress 构建,文档内容以 backend-Go handler 源码为权威依据