身份认证
交互使用时用浏览器 OAuth 登录,脚本和 CI 中用 API key,并在两者之间切换。
CLI 提供两种认证方式,分别对应两个命令命名空间:
- OAuth 登录 ——
listenhub auth login会打开浏览器,以 ListenHub 用户身份登录,并保存一个可刷新的 token。裸命令(listenhub podcast …、listenhub tts …)以该用户身份运行。 - API key —— 以
lh_sk_…开头的 key 为listenhub openapi …命令提供认证。你通过环境变量或存储的配置文件来设置它。这是服务器、脚本和 CI 场景使用的模式。
两种模式使用各自独立的凭据文件,互不干扰。你可以同时配置两者。
| OAuth 登录 | API key | |
|---|---|---|
| 配置方式 | listenhub auth login | listenhub openapi config set-key 或 LISTENHUB_API_KEY |
| 适用命令 | 裸命令(listenhub <cmd>) | listenhub openapi <cmd> |
| 身份 | 已登录用户 | key 所有者 |
| 存储位置 | ~/.config/listenhub/credentials.json | ~/.config/listenhub/openapi.json(或环境变量) |
| 适用场景 | 自己机器上的交互操作 | 脚本、CI/CD、自动化 |
两个凭据文件都位于 ~/.config/listenhub/ 下。若设置了 XDG_CONFIG_HOME,CLI 会改用 $XDG_CONFIG_HOME/listenhub/。文件以 0600 权限写入(仅所有者可读写)。
OAuth 登录
当你在自己控制的机器上交互式工作时,使用 OAuth。不会有长期凭据被写进脚本 —— CLI 持有一个短期访问 token 加一个刷新 token,并自动续期。
登录
listenhub auth login这会执行一次性的浏览器流程:
CLI 在本地随机端口(127.0.0.1)启动一个临时回调服务器,并打开默认浏览器跳转到 ListenHub 登录页。
你在浏览器中登录(如有提示则授权)。ListenHub 携带授权码重定向回本地回调。
CLI 用授权码换取 token,写入 ~/.config/listenhub/credentials.json,并打印登录的账户:
✓ Logged in as Ada Lovelace浏览器流程有 5 分钟超时。若你未在该时间窗口内完成登录,命令会以 Login timed out after 5 minutes 中止 —— 重新运行 listenhub auth login 即可。若浏览器没有自动打开,登录 URL 会打印在终端,手动打开即可。
查看状态
listenhub auth status✓ Logged in as Ada Lovelace
Email: ada@example.com
Expires at: 2026-07-01T12:00:00.000Zstatus 会用当前 token 调用 API,确认它仍然有效。加上 --json 可得到机器可读形式:
listenhub auth status --json{
"loggedIn": true,
"user": "Ada Lovelace",
"email": "ada@example.com",
"expiresAt": "2026-07-01T12:00:00.000Z"
}若你未登录,或 token 已过期且无法使用,status 会如实报告并以非零码退出:
{ "loggedIn": false }登出
listenhub auth logout这会在服务器端吊销你的刷新 token,然后删除本地的 credentials.json:
✓ Logged out如果远程吊销调用失败(例如你处于离线状态),CLI 会打印一条警告,并仍然清除本地凭据,因此无论如何机器都会处于登出状态。
Token 存储与刷新
credentials.json 保存访问 token、刷新 token 和一个 expiresAt 时间戳。你无需手动刷新 token —— 运行命令时,CLI 会按需用刷新 token 续期访问 token。该文件以原子方式写入(先写临时文件再重命名),权限为 0600。
请像对待其他密钥一样对待 credentials.json。在你运行 listenhub auth logout 或刷新 token 被吊销之前,它都拥有对你 ListenHub 账户的访问权限。
API key
当命令运行在无法完成浏览器流程的环境时,使用 API key —— CI 流水线、定时任务、服务器。API key 认证驱动 listenhub openapi … 命名空间。
在 listenhub.ai/settings/api-keys 创建 key。key 以 lh_sk_ 开头。
提供 key 有两种方式。环境变量始终优先于存储的文件。
环境变量
在 shell 或 CI secret 中设置 LISTENHUB_API_KEY:
export LISTENHUB_API_KEY="lh_sk_your_key_here"
listenhub openapi speakers list --language en这是 CI/CD 的推荐做法:把 key 放在平台的 secret 存储里,以环境变量形式注入。不会有任何内容写入磁盘。
存储配置
若需在本地反复使用,可一次性存储该 key:
listenhub openapi config set-key命令会提示输入 key(输入写到 stderr,因此不会进入管道输出),校验它以 lh_sk_ 开头,并以 0600 权限写入 ~/.config/listenhub/openapi.json。随后回显一条脱敏确认:
✓ API Key saved (lh_sk_***)不以 lh_sk_ 开头的 key 会在保存任何内容之前被拒绝:
✗ Invalid API Key format. Must start with "lh_sk_".查看与清除
查看当前生效的 key 及其来源:
listenhub openapi config show✓ API Key configured (source: env)
Key ID: lh_sk_***当设置了 LISTENHUB_API_KEY 时 source 为 env,当 key 来自 openapi.json 时为 file。完整 key 从不会被打印 —— 只显示脱敏后的 lh_sk_*** 前缀。加上 --json 便于脚本处理:
listenhub openapi config show --json{ "source": "env", "keyId": "lh_sk_live" }若未配置任何 key,show 会如实报告并以非零码退出。
移除存储的 key(这只清除文件,不会取消设置环境变量):
listenhub openapi config clear✓ API Key clearedAPI key 是与你账户绑定的长期密钥。切勿提交到源码管理,也不要粘贴进共享日志。在 CI 中优先使用来自 secret 存储的 LISTENHUB_API_KEY;仅在你自己控制的机器上使用存储配置。
我该用哪种模式?
- 在自己机器上交互式工作 → OAuth 登录。避免把长期 key 留在磁盘上,且命令以你的身份运行。
- 脚本、CI/CD、服务器 → 通过
LISTENHUB_API_KEY使用 API key。无需浏览器即可工作,且能接入 secret 管理器。
两者相互独立。常见配置是:日常终端工作用 OAuth 登录,CI 中用 API key —— 同一台机器上可同时配置两者而不冲突。
认证错误排查
CLI 使用 退出码 2 表示认证失败,因此脚本可以把「未授权」与其他错误区分开(1 = 通用错误,3 = 超时)。错误信息写到 stderr。
常见情况及修复:
| 现象 | 原因 | 修复 |
|---|---|---|
No API Key configured | 既未设置 LISTENHUB_API_KEY,也没有存储的 key | 运行 listenhub openapi config set-key,或导出 LISTENHUB_API_KEY |
Invalid API Key format. Must start with "lh_sk_" | 输入的 key 前缀不对 | 从 settings/api-keys 复制一个新 key;key 以 lh_sk_ 开头 |
auth status 报 Not logged in (token expired or invalid) | OAuth token 已过期或被吊销 | 再次运行 listenhub auth login |
已 config set-key,但 openapi 命令仍报认证错误 | LISTENHUB_API_KEY 被设为陈旧/错误的值并覆盖了文件 | unset LISTENHUB_API_KEY(环境变量优先于存储配置),或修正该变量 |
Login timed out after 5 minutes | 未在限定时间内完成浏览器流程 | 重新运行 listenhub auth login 并尽快完成登录 |
确认 CLI 当前所看到的状态:
listenhub auth status # OAuth 会话
listenhub openapi config show # API key 来源(env 还是 file)