feishu-cli-auth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese飞书 OAuth 认证与 Token 管理
飞书 OAuth 认证与 Token 管理
feishu-cli 通过 OAuth 2.0 Authorization Code Flow 获取 User Access Token,用于搜索等需要用户身份的 API。
feishu-cli 通过 OAuth 2.0 Authorization Code Flow 获取 User Access Token,用于搜索等需要用户身份的 API。
核心概念
核心概念
Token 存储位置:所有 OAuth Token 保存在 ,包括 Access Token、Refresh Token、过期时间和授权 scope。登录、刷新、退出等操作都围绕此文件进行。
~/.feishu-cli/token.json两种身份:
- App Access Token(应用身份):通过 app_id/app_secret 自动获取,大多数文档操作使用此身份
- User Access Token(用户身份):需 OAuth 授权,搜索 API 必须使用此身份
Token 生命周期:
- Access Token:2 小时有效
- Refresh Token:30 天有效(需 scope)
offline_access - 过期后自动用 Refresh Token 刷新,用户无感
Token 存储位置:所有OAuth Token均存储在 中,包括 Access Token、Refresh Token、过期时间及授权 scope。登录、刷新、退出等操作均围绕该文件展开。
~/.feishu-cli/token.json两种身份:
- App Access Token(应用身份):通过 app_id/app_secret 自动获取,大多数文档操作使用此身份
- User Access Token(用户身份):需 OAuth 授权,搜索 API 必须使用此身份
Token 生命周期:
- Access Token:2 小时有效
- Refresh Token:30 天有效(需 scope)
offline_access - 过期后自动用 Refresh Token 刷新,用户无感
两步式非交互登录(AI Agent 推荐)
两步式非交互登录(AI Agent 推荐)
AI Agent 的 Bash tool 无法进行交互式 stdin 输入,因此 模式不可用。使用 + 两步式流程:
--manual--print-urlauth callbackAI Agent 的 Bash tool 无法进行交互式 stdin 输入,因此 模式不可用。使用 + 两步式流程:
--manual--print-urlauth callback步骤 1:生成授权 URL
步骤 1:生成授权 URL
始终使用最大 scope 范围授权,一次性覆盖 feishu-cli 所有用户身份功能,避免后续因 scope 不足导致 99991679 错误:
bash
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"输出 JSON(stdout):
json
{
"auth_url": "https://accounts.feishu.cn/open-apis/authen/v1/authorize?...",
"state": "随机64字符十六进制字符串",
"redirect_uri": "http://127.0.0.1:9768/callback"
}立即返回,不阻塞,不启动 HTTP 服务器。
将 展示给用户,请用户在浏览器中打开并完成授权。授权后浏览器会跳转到一个无法访问的页面(),这是正常的——让用户复制地址栏中的完整 URL。
auth_url127.0.0.1:9768/callback?code=xxx&state=yyy始终使用最大 scope 范围授权,一次性覆盖 feishu-cli 所有用户身份功能,避免后续因 scope 不足导致 99991679 错误:
bash
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"输出 JSON(stdout):
json
{
"auth_url": "https://accounts.feishu.cn/open-apis/authen/v1/authorize?...",
"state": "随机64字符十六进制字符串",
"redirect_uri": "http://127.0.0.1:9768/callback"
}立即返回,不阻塞,不启动 HTTP 服务器。
将 展示给用户,请用户在浏览器中打开并完成授权。授权后浏览器会跳转到一个无法访问的页面(),这是正常的——让用户复制地址栏中的完整 URL。
auth_url127.0.0.1:9768/callback?code=xxx&state=yyy步骤 2:用回调 URL 换 Token
步骤 2:用回调 URL 换 Token
bash
feishu-cli auth callback "<回调URL>" --state "<步骤1输出的state>"输出 JSON(stdout)+ 人类可读信息(stderr):
json
{
"status": "success",
"expires_at": "2026-03-09T04:31:11+08:00",
"scope": "auth:user.id:read search:docs:read search:message offline_access"
}Token 自动保存到 。
~/.feishu-cli/token.jsonbash
feishu-cli auth callback "<回调URL>" --state "<步骤1输出的state>"输出 JSON(stdout)+ 人类可读信息(stderr):
json
{
"status": "success",
"expires_at": "2026-03-09T04:31:11+08:00",
"scope": "auth:user.id:read search:docs:read search:message offline_access"
}Token 自动保存到 。
~/.feishu-cli/token.jsonauth callback 常见错误
auth callback 常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| 授权 code 有效期约 5 分钟,用户复制回调 URL 太慢 | 重新执行步骤 1 获取新的授权 URL,提醒用户尽快完成 |
| | 确保 |
| 网络超时 / 连接失败 | 无法访问飞书 OAuth 服务器(网络不通或代理问题) | 检查网络连通性,确认能访问 |
| 错误 | 原因 | 解决 |
|---|---|---|
| 授权 code 有效期约 5 分钟,用户复制回调 URL 太慢 | 重新执行步骤 1 获取新的授权 URL,提醒用户尽快完成 |
| | 确保 |
| 网络超时 / 连接失败 | 无法访问飞书 OAuth 服务器(网络不通或代理问题) | 检查网络连通性,确认能访问 |
完整示例
完整示例
bash
undefinedbash
undefined步骤 1(使用最大 scope 范围)
步骤 1(使用最大 scope 范围)
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
→ 展示 auth_url 给用户,用户浏览器授权后复制回调 URL
→ 展示 auth_url 给用户,用户浏览器授权后复制回调 URL
步骤 2(用步骤 1 的 state 和用户提供的回调 URL)
步骤 2(用步骤 1 的 state 和用户提供的回调 URL)
feishu-cli auth callback "http://127.0.0.1:9768/callback?code=xxx&state=yyy" --state "yyy"
---feishu-cli auth callback "http://127.0.0.1:9768/callback?code=xxx&state=yyy" --state "yyy"
---Scope 配置
Scope 配置
scope 决定了 Token 能访问哪些 API。登录时通过 指定(空格分隔)。scope 名称 = 飞书开放平台开发者后台的权限名称,最多 50 个,多次授权累加生效。
--scopesscope 决定了 Token 能访问哪些 API。登录时通过 指定(空格分隔)。scope 名称 = 飞书开放平台开发者后台的权限名称,最多 50 个,多次授权累加生效。
--scopes默认策略:始终使用最大 scope
默认策略:始终使用最大 scope
每次登录都使用以下完整 scope 列表,一次性覆盖 feishu-cli 全部用户身份功能。避免因 scope 不足导致部分命令报 99991679 错误:
offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly每次登录都使用以下完整 scope 列表,一次性覆盖 feishu-cli 全部用户身份功能。避免因 scope 不足导致部分命令报 99991679 错误:
offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonlyToken 使用策略
Token 使用策略
feishu-cli 的 wiki、calendar、task、msg 等命令通过 支持可选的用户身份。这些命令默认使用 App Token(租户身份),不会自动从 token.json 加载 User Token。只有在以下情况才使用 User Token:
resolveOptionalUserToken- 通过 参数显式传入
--user-access-token - 通过 环境变量显式设置
FEISHU_USER_ACCESS_TOKEN
搜索命令()通过 必须使用 User Token,会从 token.json 自动加载。
search docs/messages/appsresolveRequiredUserTokenfeishu-cli 的 wiki、calendar、task、msg 等命令通过 支持可选的用户身份。这些命令默认使用 App Token(租户身份),不会自动从 token.json 加载 User Token。只有在以下情况才使用 User Token:
resolveOptionalUserToken- 通过 参数显式传入
--user-access-token - 通过 环境变量显式设置
FEISHU_USER_ACCESS_TOKEN
搜索命令()通过 必须使用 User Token,会从 token.json 自动加载。
search docs/messages/appsresolveRequiredUserTokenScope 完整说明
Scope 完整说明
| scope | 作用 | 对应命令 |
|---|---|---|
| 获取 Refresh Token(30 天有效) | 必须包含,否则 2 小时后需重新登录 |
| 搜索云文档 | |
| 搜索消息 | |
| 搜索云空间文件 | |
| 知识库读取(用户身份) | |
| 日历读取 | |
| 日历事件读取 | |
| 创建日历事件 | |
| 更新日历事件 | |
| 回复日历事件 | |
| 忙闲查询 | |
| 任务读取 | |
| 任务写入 | |
| 任务列表读取 | |
| 任务列表写入 | |
| 消息历史读取 | |
| 用户身份读取群消息 | |
| 群聊信息读取 | |
| 用户信息读取 | |
| 文件元数据读取 | |
| 用户身份信息 | 通常自动包含 |
| scope | 作用 | 对应命令 |
|---|---|---|
| 获取 Refresh Token(30 天有效) | 必须包含,否则 2 小时后需重新登录 |
| 搜索云文档 | |
| 搜索消息 | |
| 搜索云空间文件 | |
| 知识库读取(用户身份) | |
| 日历读取 | |
| 日历事件读取 | |
| 创建日历事件 | |
| 更新日历事件 | |
| 回复日历事件 | |
| 忙闲查询 | |
| 任务读取 | |
| 任务写入 | |
| 任务列表读取 | |
| 任务列表写入 | |
| 消息历史读取 | |
| 用户身份读取群消息 | |
| 群聊信息读取 | |
| 用户信息读取 | |
| 文件元数据读取 | |
| 用户身份信息 | 通常自动包含 |
前提条件
前提条件
scope 中的权限必须先在飞书开放平台 → 应用详情 → 权限管理中启用。未启用的权限在授权时会被忽略或报错 20027。
scope 中的权限必须先在飞书开放平台 → 应用详情 → 权限管理中启用。未启用的权限在授权时会被忽略或报错 20027。
常见错误
常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| Token 的 scope 不包含目标 API 权限 | 重新登录,使用最大 scope |
| Refresh Token 为空 | 缺少 | 重新登录,使用最大 scope |
| 开发者后台未启用该权限 | 在飞书开放平台启用对应权限后重新授权 |
| 错误 | 原因 | 解决 |
|---|---|---|
| Token 的 scope 不包含目标 API 权限 | 重新登录,使用最大 scope |
| Refresh Token 为空 | 缺少 | 重新登录,使用最大 scope |
| 开发者后台未启用该权限 | 在飞书开放平台启用对应权限后重新授权 |
Token 状态检查
Token 状态检查
bash
undefinedbash
undefined人类可读格式
人类可读格式
feishu-cli auth status
feishu-cli auth status
JSON 格式(AI Agent 推荐)
JSON 格式(AI Agent 推荐)
feishu-cli auth status -o json
**当已登录且 Token 有效时:**
```json
{
"logged_in": true,
"access_token_valid": true,
"access_token_expires_at": "2026-03-09T04:32:19+08:00",
"refresh_token_valid": true,
"refresh_token_expires_at": "2026-03-16T02:32:19+08:00",
"scope": "auth:user.id:read search:docs:read search:message offline_access"
}当未登录时:
json
{"logged_in": false}feishu-cli auth status -o json
**当已登录且 Token 有效时:**
```json
{
"logged_in": true,
"access_token_valid": true,
"access_token_expires_at": "2026-03-09T04:32:19+08:00",
"refresh_token_valid": true,
"refresh_token_expires_at": "2026-03-16T02:32:19+08:00",
"scope": "auth:user.id:read search:docs:read search:message offline_access"
}当未登录时:
json
{"logged_in": false}状态判断逻辑
状态判断逻辑
logged_in=false → 从未登录,需要 auth login
access_token_valid=true → 正常可用
access_token_valid=false + refresh_token_valid=true → 下次调用时自动刷新,无需操作
access_token_valid=false + refresh_token_valid=false → 需要重新 auth login
scope 中无目标权限 → 需要重新登录并补充 scopelogged_in=false → 从未登录,需要 auth login
access_token_valid=true → 正常可用
access_token_valid=false + refresh_token_valid=true → 下次调用时自动刷新,无需操作
access_token_valid=false + refresh_token_valid=false → 需要重新 auth login
scope 中无目标权限 → 需要重新登录并补充 scopeToken 自动刷新机制
Token 自动刷新机制
搜索等必须 User Access Token 的命令()通过 按以下优先级链查找。其他可选命令()仅检查第 1、2 项,默认使用 App Token:
resolveRequiredUserTokenResolveUserAccessToken()resolveOptionalUserToken- 命令行参数
--user-access-token - 环境变量
FEISHU_USER_ACCESS_TOKEN - :
~/.feishu-cli/token.json- access_token 有效 → 直接使用
- access_token 过期 + refresh_token 有效 → 自动刷新并保存新 Token
- 都过期 → 报错"已过期,请重新登录"
- 中的
config.yaml静态配置user_access_token - 全部为空 → 报错"缺少 User Access Token",列出 4 种获取方式
刷新过程对用户透明:stderr 输出 ,命令正常执行。
[自动刷新] 刷新成功...搜索等必须 User Access Token 的命令()通过 按以下优先级链查找。其他可选命令()仅检查第 1、2 项,默认使用 App Token:
resolveRequiredUserTokenResolveUserAccessToken()resolveOptionalUserToken- 命令行参数
--user-access-token - 环境变量
FEISHU_USER_ACCESS_TOKEN - :
~/.feishu-cli/token.json- access_token 有效 → 直接使用
- access_token 过期 + refresh_token 有效 → 自动刷新并保存新 Token
- 都过期 → 报错"已过期,请重新登录"
- 中的
config.yaml静态配置user_access_token - 全部为空 → 报错"缺少 User Access Token",列出 4 种获取方式
刷新过程对用户透明:stderr 输出 ,命令正常执行。
[自动刷新] 刷新成功...User Access Token 的使用场景
User Access Token 的使用场景
必需 User Access Token 的命令
必需 User Access Token 的命令
| 命令 | 需要的 scope |
|---|---|
| |
| |
| (需确认应用是否已开通搜索应用权限) |
| 命令 | 需要的 scope |
|---|---|
| |
| |
| (需确认应用是否已开通搜索应用权限) |
可选 User Access Token 的命令
可选 User Access Token 的命令
以下命令通过 支持可选的用户身份——默认使用 App Token(租户身份),仅在通过 参数或 环境变量显式指定时才使用 User Token:
resolveOptionalUserToken--user-access-tokenFEISHU_USER_ACCESS_TOKEN| 命令类别 | 需要的 scope |
|---|---|
| |
| |
| |
| |
| |
| |
以下命令通过 支持可选的用户身份——默认使用 App Token(租户身份),仅在通过 参数或 环境变量显式指定时才使用 User Token:
resolveOptionalUserToken--user-access-tokenFEISHU_USER_ACCESS_TOKEN| 命令类别 | 需要的 scope |
|---|---|
| |
| |
| |
| |
| |
| |
登录前的检查流程
登录前的检查流程
bash
undefinedbash
undefined1. 检查是否已登录且 Token 有效
1. 检查是否已登录且 Token 有效
feishu-cli auth status -o json
feishu-cli auth status -o json
2. 如果未登录或已过期,执行两步式登录(使用最大 scope)
2. 如果未登录或已过期,执行两步式登录(使用最大 scope)
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
feishu-cli auth login --print-url --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
... 用户授权 ...
... 用户授权 ...
feishu-cli auth callback "<回调URL>" --state "<state>"
feishu-cli auth callback "<回调URL>" --state "<state>"
3. 登录后搜索命令自动从 token.json 读取 Token
3. 登录后搜索命令自动从 token.json 读取 Token
feishu-cli search docs "产品需求"
feishu-cli search docs "产品需求"
其他命令默认使用 App Token,需要时可显式传 --user-access-token
其他命令默认使用 App Token,需要时可显式传 --user-access-token
feishu-cli wiki export <node_token> -o doc.md
feishu-cli task create --summary "待办事项"
---feishu-cli wiki export <node_token> -o doc.md
feishu-cli task create --summary "待办事项"
---其他登录模式
其他登录模式
除 AI Agent 的两步式外,还有两种人类用户直接使用的模式(同样使用最大 scope):
bash
undefined除 AI Agent 的两步式外,还有两种人类用户直接使用的模式(同样使用最大 scope):
bash
undefined本地桌面环境(默认):自动打开浏览器 + 本地 HTTP 回调
本地桌面环境(默认):自动打开浏览器 + 本地 HTTP 回调
feishu-cli auth login --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
feishu-cli auth login --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
远程 SSH 环境:打印 URL,用户手动粘贴回调 URL(交互式 stdin)
远程 SSH 环境:打印 URL,用户手动粘贴回调 URL(交互式 stdin)
feishu-cli auth login --manual --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
undefinedfeishu-cli auth login --manual --scopes "offline_access search:docs:read search:message drive:drive.search:readonly wiki:wiki:readonly calendar:calendar:read calendar:calendar.event:read calendar:calendar.event:create calendar:calendar.event:update calendar:calendar.event:reply calendar:calendar.free_busy:read task:task:read task:task:write task:tasklist:read task:tasklist:write im:message:readonly im:message.group_msg:get_as_user im:chat:read contact:user.base:readonly drive:drive.metadata:readonly"
undefined前置条件
前置条件
在飞书开放平台 → 应用详情 → 安全设置 → 重定向 URL 中添加:
http://127.0.0.1:9768/callback如果使用自定义端口(),需添加对应的重定向 URL。
--port 8080在飞书开放平台 → 应用详情 → 安全设置 → 重定向 URL 中添加:
http://127.0.0.1:9768/callback如果使用自定义端口(),需添加对应的重定向 URL。
--port 8080退出登录
退出登录
bash
feishu-cli auth logout删除 ,不影响 App Access Token(app_id/app_secret)。
~/.feishu-cli/token.jsonbash
feishu-cli auth logout删除 ,不影响 App Access Token(app_id/app_secret)。
~/.feishu-cli/token.json排错指南
排错指南
| 问题 | 诊断 | 解决 |
|---|---|---|
| "缺少 User Access Token" | 从未登录 | 执行 |
| "User Access Token 已过期" | token.json 中 access + refresh 都过期 | 重新 |
| 搜索报 99991679 权限错误 | scope 不足 | 重新登录,加上缺失的 scope |
| Refresh Token 为空 | 未包含 | 重新登录,加上 |
| "state 不匹配" | | 确保使用同一次 |
| "端口被占用" | 9768 端口已被其他进程使用 | 使用 |
| stdin 阻塞 | 改用 |
| 问题 | 诊断 | 解决 |
|---|---|---|
| "缺少 User Access Token" | 从未登录 | 执行 |
| "User Access Token 已过期" | token.json 中 access + refresh 都过期 | 重新 |
| 搜索报 99991679 权限错误 | scope 不足 | 重新登录,加上缺失的 scope |
| Refresh Token 为空 | 未包含 | 重新登录,加上 |
| "state 不匹配" | | 确保使用同一次 |
| "端口被占用" | 9768 端口已被其他进程使用 | 使用 |
| stdin 阻塞 | 改用 |