前置准备
在飞书开放平台 https://open.feishu.cn/app 创建企业自建应用,记录以下信息:
App ID(即client_id)App Secret(即client_secret)
第一步:配置应用权限
- 进入应用 → 权限管理
- 搜索并开启所需权限,例如:
contact:user.base:readonly(读取用户基本信息)
- 提交审核(企业自建应用通常自动审批通过)
💡
offline_access是 OAuth 协议标准 scope,无需在权限管理中申请,直接在授权链接中添加即可。
第二步:配置重定向 URL
- 进入应用 → 安全设置
- 在「重定向 URL」中添加回调地址
重定向 URL 是你自己定义的地址,飞书授权成功后会将用户跳转到此地址并携带
code参数。
| 场景 | 填写示例 |
|---|---|
| 本地开发调试 | http://localhost:3000/callback |
| 线上服务器 | https://yourdomain.com/callback |
| 纯手动测试(无服务器) | http://localhost(从地址栏复制 code) |
第三步:引导用户授权,获取 Code
在浏览器中打开以下授权链接(注意:redirect_uri 需要 URL 编码,且整个链接必须是一行):
不需要 refresh_token(基础版):
https://open.feishu.cn/open-apis/authen/v1/authorize?client_id=YOUR_APP_ID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&response_type=code&scope=contact:user.base:readonly&state=abc123
需要 refresh_token(推荐,加上 offline_access):
https://open.feishu.cn/open-apis/authen/v1/authorize?client_id=YOUR_APP_ID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&response_type=code&scope=contact:user.base:readonly%20offline_access&state=abc123
参数说明:
| 参数 | 说明 |
|---|---|
client_id |
你的 App ID |
redirect_uri |
回调地址(需 URL 编码) |
response_type |
固定填 code |
scope |
申请的权限范围,多个值用空格分隔(URL 编码为 %20) |
state |
随机字符串,用于防 CSRF 攻击 |
scope 说明:
| scope 值 | 说明 |
|---|---|
contact:user.base:readonly |
读取用户基本信息(需在权限管理中申请) |
offline_access |
获取 refresh_token,用于后续刷新凭证(无需申请,直接加即可) |
用户点击授权后,浏览器跳转到:
http://localhost:3000/callback?code=xxxxxxxx&state=abc123
从 URL 中取出 code 参数,该 code 仅 5 分钟内有效,需立即使用!
第四步:用 Code 换取 User Access Token
⚠️ 注意:必须使用 v2 接口,v1 接口已废弃。
请求地址:
POST https://open.feishu.cn/open-apis/authen/v2/oauth/token
请求 Headers:
Content-Type: application/json
请求 Body(JSON):
{
"grant_type": "authorization_code",
"client_id": "YOUR_APP_ID",
"client_secret": "YOUR_APP_SECRET",
"code": "上一步获取的 code",
"redirect_uri": "http://localhost:3000/callback"
}
⚠️
redirect_uri在 JSON body 中不需要 URL 编码,直接填原始地址即可。
成功响应示例(含 refresh_token):
{
"token_type": "Bearer",
"access_token": "eyJhbGci...",
"expires_in": 7200,
"refresh_token": "ur-xxxxxxxxxxxxxxxx",
"scope": "contact:user.base:readonly offline_access",
"code": 0
}
💡
refresh_token仅在授权链接的 scope 中包含offline_access时才会返回,否则响应中不含此字段。
其中 access_token 就是 user_access_token。
第五步:使用 Token 调用 API
在请求头中携带 token:
Authorization: Bearer eyJhbGci...
示例------获取当前用户信息:
curl https://open.feishu.cn/open-apis/authen/v1/user_info \
-H "Authorization: Bearer eyJhbGci..."
Token 有效期说明
| Token 类型 | 有效期 |
|---|---|
access_token(user_access_token) |
2 小时 |
refresh_token |
30 天 |
刷新 Token(access_token 过期后)
前提:授权时 scope 包含了
offline_access,响应中才有refresh_token。
请求地址:
POST https://open.feishu.cn/open-apis/authen/v2/oauth/token
请求 Body(JSON):
{
"grant_type": "refresh_token",
"client_id": "YOUR_APP_ID",
"client_secret": "YOUR_APP_SECRET",
"refresh_token": "ur-xxxxxxxxxxxxxxxx"
}
成功响应会同时返回新的 access_token 和 refresh_token:
{
"token_type": "Bearer",
"access_token": "eyJhbGci...(新的)",
"expires_in": 7200,
"refresh_token": "ur-yyyyyyyyyyyyyy(新的)",
"code": 0
}
⚠️ 每次刷新后,旧的
refresh_token立即失效,请保存新返回的refresh_token。
常见错误排查
| 错误码 | 原因 | 解决方法 |
|---|---|---|
20014 |
App Access Token 无效 | 检查是否使用了 v2 接口;检查 redirect_uri 是否与授权时一致 |
| code 失效 | code 超过 5 分钟或已被使用 | 重新打开授权链接获取新 code |
| redirect_uri 不匹配 | body 中的 redirect_uri 与授权时不一致 | 确保两处完全一致,body 中不要 URL 编码 |
| 响应中无 refresh_token | 授权时未申请 offline_access | 在 scope 中加上 offline_access 重新授权 |
完整流程示意
1. 配置应用权限 & 重定向 URL
↓
2. 打开授权链接(scope 加上 offline_access)→ 用户点击同意
↓
3. 从回调 URL 中获取 code(5分钟内有效)
↓
4. POST /authen/v2/oauth/token → 获取 access_token + refresh_token
↓
5. 使用 access_token 调用飞书 API
↓
6. access_token 过期后,用 refresh_token 刷新,获取新 token