GoWVP 开发者鉴权方案指南
本文档面向系统集成开发者与前端开发者,详细介绍 GoWVP(OWL)提供的三种接口鉴权机制、设计原理、配置方式及调用示例。
1. 鉴权方案概览
GoWVP 支持以下三种鉴权模式,三种模式在网关中间件中无缝协同、层层兜底:
| 鉴权方案 | 凭据形态 | 时效性 | 权限等级 | 核心适用场景 |
|---|---|---|---|---|
| APISecret 静态秘钥 | 固定字符串 | 永久有效(直至配置变更) | 默认管理员(admin) | 外部系统集成、自动化脚本、后台监控、长期微服务通信 |
| JWT 动态令牌 | 三段式 Base64 签名串 | 动态过期(默认3天) | 按登录身份签发 | Web 前端用户登录、管理控制台、交互式客户端 |
| 第三方 AuthURL | 透传原始 Header/Body | 由第三方服务判定 | 由第三方服务控制 | 企业已有 SSO 单点登录、统一认证中心、集中权限网关 |
2. 鉴权流程与决策链路
当客户端向受保护接口发起请求时,中间件遵循**“静态优先、动态验签、远程兜底”**的过滤机制:
客户端请求 (Header: Authorization / Query: token) │ ▼ 提取 tokenStr (剥离可选 Bearer 前缀) │ ▼ [配置了 APISecret 且凭据完全匹配?] ├── 是 ──► 注入管理员上下文 (username=admin, role=admin) ──► 放行 (200) └── 否 │ ▼ [凭据为 Bearer 前缀且 JWT 解析成功?] ├── 成功 ──► 注入 JWT Claims ──► 放行 (200) ├── 过期 ──► 直接拦截 (401 Token Expired, 要求重新登录) └── 失败 │ ▼ [是否配置了第三方 AuthURL?] ├── 是 ──► 原样透传 Header 与 Body 至远程鉴权服务 │ ├── 远程返回 200 ──► 放行 │ └── 远程返回非 200 ──► 原样透传远程响应状态与内容 └── 否 ──► 拦截 (401 身份验证失败)关键设计优势
- 零性能损耗:APISecret 采用
crypto/subtle.ConstantTimeCompare常数时间比对,既规避了时序侧信道攻击,又无需执行耗时的 Base64 解码与数字验签,高频 API 调用耗时仅纳秒级。 - 长短互补:日常开发管理使用 JWT 保证会话时效安全性;后端脚本或跨节点同步使用 APISecret,避免定时轮询刷新 Token 的复杂心跳逻辑。
- 接口调用一致性:无论使用哪种鉴权方式,均支持标准的 HTTP
Authorization: Bearer <token>头部,调用方无须更改请求头封装。
3. 方案详解与调用示例
方案一:APISecret 永久秘钥鉴权
适用于自动化巡检、Prometheus 指标拉取、流媒体节点纳管、外部业务系统服务端调用。
1. 规约与格式
- 密钥仅允许由数字、大小写字母、下划线组成。
- 长度限制:1 ~ 32 位。
- 系统在每次启动时会自动校验此配置项:
- 若配置为空,系统将自动生成 32 位无连字符 UUID,并持久化回写至
config.toml; - 若配置了非法字符或超长,系统会打印 WARN 警告日志,并自动重新生成合规的 32 位秘钥覆盖持久化。
- 若配置为空,系统将自动生成 32 位无连字符 UUID,并持久化回写至
2. 配置文件 (configs/config.toml)
[Server.HTTP] # 永久 API 秘钥,替代 JWT 鉴权 APISecret = 'my_secure_api_secret_2026'3. 调用方式
支持两种传参途径:
- Header 方式(推荐):
curl-H"Authorization: Bearer my_secure_api_secret_2026"http://127.0.0.1:15123/debug/sip/memory - URL Query 方式(适合浏览器直连、播放器拉流或轻量 Webhook):
curl"http://127.0.0.1:15123/debug/sip/memory?token=my_secure_api_secret_2026"
方案二:JWT 动态令牌鉴权
适用于 Web 管理控制台、App 客户端等需要用户登录交互的场景。
1. 获取令牌
调用系统登录接口获取 JWT Token:
curl-XPOST http://127.0.0.1:15123/api/v1/user/login\-H"Content-Type: application/json"\-d'{"username": "admin", "password": "your_password"}'响应体示例:
{"reason":"OK","msg":"success","details":[],"trace_id":"0191e4b3-a123-74b8-8c12-3456789abcde","data":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","user":"admin"}}2. 调用受保护接口
在请求头中携带 Token:
curl-H"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."http://127.0.0.1:15123/app/network/subnets3. 过期与鉴权失败处理
当 Token 超过签发有效期(默认 3 天)时,接口会直接返回 401 统一错误响应:
{"reason":"ErrUnauthorizedToken","msg":"请重新登录","details":[],"trace_id":"0191e4b3-a123-74b8-8c12-3456789abcde"}若未传递凭证或凭据非法且无第三方鉴权服务兜底时,接口返回:
{"reason":"ErrUnauthorizedToken","msg":"身份验证失败","details":[],"trace_id":"0191e4b3-a123-74b8-8c12-3456789abcde"}此时客户端需重新发起登录换取新 Token。
方案三:第三方 AuthURL 转发鉴权
适用于企业内部已有统一账号与权限体系(如 OAuth2、CAS、统一网关服务),希望将 GoWVP 的鉴权委托给自研鉴权服务。
1. 配置文件 (configs/config.toml)
[Server.HTTP] # 填写第三方鉴权服务的 HTTP 地址,留空表示不启用 AuthURL = 'http://auth.internal.company.com/verify'2. 工作原理
- 当客户端发起的请求未命中 APISecret,且未通过系统原生 JWT 验签时,中间件将原始 HTTP 请求的所有 Header 与 Body 原样 POST 转发给
AuthURL。 - 规则裁决:
- 若第三方鉴权服务返回 HTTP 状态码
200 OK:GoWVP 判定鉴权通过,继续执行接口逻辑; - 若第三方服务返回其他状态码(如 401、403、500 等):GoWVP 直接将该响应状态码和响应体原样输出给客户端。
- 若第三方鉴权服务返回 HTTP 状态码
4. 多语言代码集成示例
Python
importrequests# 方式一:使用 APISecretheaders={"Authorization":"Bearer my_secure_api_secret_2026"}resp=requests.get("http://127.0.0.1:15123/app/network/subnets",headers=headers)print(resp.json())# 方式二:URL Query 传参resp_query=requests.get("http://127.0.0.1:15123/app/network/subnets?token=my_secure_api_secret_2026")print(resp_query.json())Go
packagemainimport("fmt""io""net/http")funcmain(){client:=&http.Client{}req,_:=http.NewRequest("GET","http://127.0.0.1:15123/app/network/subnets",nil)req.Header.Set("Authorization","Bearer my_secure_api_secret_2026")resp,err:=client.Do(req)iferr!=nil{panic(err)}deferresp.Body.Close()body,_:=io.ReadAll(resp.Body)fmt.Println(string(body))}JavaScript / TypeScript (Fetch)
constAPI_URL="http://127.0.0.1:15123/app/network/subnets";constAPI_SECRET="my_secure_api_secret_2026";asyncfunctionfetchSubnets(){constresponse=awaitfetch(API_URL,{method:"GET",headers:{"Authorization":`Bearer${API_SECRET}`}});constdata=awaitresponse.json();console.log(data);}5. 安全最佳实践
- 生产环境秘钥保护:APISecret 具备全站最高管理员权限,且永不过期,严禁提交到开源仓库或前端代码中。
- 结合 HTTPS / 反向代理:建议在生产环境中通过 Nginx 启用 HTTPS,避免明文 HTTP 传输导致网络窃听。
- 内外网隔离:若对外暴露接口,建议限制 APISecret 仅在受信任的内网 IP 段使用,或在反向代理层限制特定路径。