Appearance
插件身份凭证
概述
要调用飞书项目开放平台服务端open api,插件需要获取对应的身份凭证(plugin_token);插件身份凭证代表插件从平台/用户手中获取的授权。获取身份凭证的流程如下:
- 在飞书项目开放平台(平台左下角,点击头像,然后选择进入开放平台)注册插件
- 在开发者后台勾选插件所需权限并发布上架插件
身份凭证
飞书项目开放平台提供了三种类型的plugin_token,用于验证调用方身份、确保调用方具有执行操作所需要的权限:
plugin_token:插件身份凭证,开放平台可据此识别调用方的插件身份。调用接口时:开放平台会根据操作对应的飞书项目租户/空间是否安装该插件来判断是否具有相应的操作权限。举个例子:获取一个空间下的所有需求列表。同时,插件身份凭证也代表了插件的独立身份,可以理解为插件本身也是一个用户。举个例子:插件A通过api+ plugin_token对某个需求添加一条评论,评论者的署名就是插件A。
虚拟plugin_token:仅供开发调试使用,是一种特殊的plugin_token。此种token不受插件发版影响,用户在「开发者后台」勾选api接口访问权限后即时生效,其中接口中的访问数据范围为用户在「权限管理」页面中勾选的空间。
user_plugin_token:用户身份凭证,代表了用户对插件的临时授权,使用该token,插件将代表用户执行对应的操作。比如用户小王给插件A授权,通过api+ user_plugin_token对某个需求添加一条评论,评论者的署名就是小王。
三种token的示例及获取方式如下:
身份凭证 | 示例 | 获取方式 |
plugin_token | p-b0dc4a7d-9080-4bc3-b54a-76b680565b1a | |
虚拟plugin_token | v-b0dc4a7d-9080-4bc3-b54a-76b680565b1a | |
user_plugin_token | u-f09b09b8-e78a-405b-9733-7261787ee6ec |
如何使用身份凭证
两种token的使用方式相同,在进行API调用时,需要将token放入请求Header中,key为:X-Plugin-Token。下面是调用API查询需求详情的示例: bash
curl --location --request GET 'https://{平台域名}/open_api/v1/project/week/story/2187937' \
--header 'X-Plugin-Token: p-b0dc4a7d-9080-4bc3-b54a-76b680565b1a' \
--header 'X-User-Key : 6981236459583848476' \
--header 'Content-Type: application/' \
curl --location --request GET 'https://{平台域名}/open_api/v1/project/week/story/2187937' \
--header 'X-Plugin-Token: u-f09b09b8-e78a-405b-9733-7261787ee6ec' \
--header 'Content-Type: application/' \
请注意:接口请求域名请以平台域名为准。
获取plugin_token
Token 有效期为 2 小时,在此期间调用该接口 token 不会改变,有效期返回最新的倒计时时间。当 token 有效期小于 5 分的时候,再次请求获取 token 的时候,会生成一个新的 token,与此同时老的 token 依然有效。
请求
基本信息 | |
HTTP URL | https://{平台域名}/bff/v2/authen/plugin_token |
HTTP Method | POST |
HTTP Content-Type | application/ |
请求体
参数 | 类型 | 是否必填 | 示例 | 说明 |
plugin_id | string | 是 | MII_60D0814C4B80012C | 插件唯一标识,创建插件后获得。获取方式:飞书项目插件开发与发布指南 |
plugin_secret | string | 是 | AE20CC20B88168FC2F5384E13C904F92 | 插件秘钥,创建插件后获得。获取方式:飞书项目插件开发与发布指南 |
type | int | 否 | 0,1 | 0为plugin_token,1为虚拟plugin_token |
响应体
data | ||
参数 | 类型 | 说明 |
token | string | token值 |
expire_time | int | 失效时间 |
error | ||
参数 | 类型 | 说明 |
code | int | 错误码,非0表示失败 |
msg | string | 错误描述 |
CURL示例
请求示例:
curl --location --request POST 'https://{平台域名}/bff/v2/authen/plugin_token' \
--header 'Content-Type: application/' \
--data-raw '{
"plugin_id": "MII_60D0814C4B80012C",
"plugin_secret": "AE20CC20B88168FC2F5384E13C904F92"
}'
返回结果如下:
{
"data": {
"token": "p-24af8f8f-290f-4fc7-86e1-b592e46dee43",
"expire_time": 7200,
},
"error": {
"code": 0,
"msg": "success"
}
}
获取user_plugin_token(第三方免登)
获取user_plugin_token要经过用户授权流程,流程如下:
第三方发起授权登录请求,飞书项目用户允许授权第三方插件。
飞书项目重定向到第三方网站,并且带上授权临时票据code参数;
使用code、plugin_token等,通过API换取user_plugin_token;
暂时无法在飞书文档外展示此内容
示例
一、创建插件,获取plugin ID 和plugin Secret
二、获取登录授权码
目前请求仅支持从飞书项目 PC端发起,前端插件应使用飞书项目登录组件发起获取授权码请求。
原理是,前端组件会将飞书项目的登录session key带到header里请求开放平台“获取登录授权码”接口。
如下操作,可以在Postman进行调试,模拟组件登录过程。
Authoration Token(如果没有找到这个token,请看下面的:使用cookie获取code的流程)
- 登录飞书项目,拿到飞书项目侧session key。
- 构造登录curl。
curl --location --request POST 'https://{平台域名}/bff/v2/authen/v1/auth_code' \
--header 'X-TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Im5pY2tuYW1lIjoi5p2O5oCh5ZCbIiwiZW1haWwiOiJsaXlpanVuLmxhcmtAYnl0ZWRhbmNlLmNvbSIsInVzZXJuYW1lIjoibGl5aWp1bi5sYXJrIiwidXNlcl90eXBlIjowLCJhdmF0YXJfdXJsIjoiaHR0cHM6Ly9zMy1mcy5wc3RhdHAuY29tL3N0YXRpYy1yZXNvdXJjZS92MS9hYzgzNGMzYS1hNjFjLTQ2OTEtYjFiMy00MzM5ZjhiNjRhZWd-P2ltYWdlX3NpemU9NzJ4NzJcdTAwMjZjdXRfdHlwZT1cdTAwMjZxdWFsaXR5PVx1MDAyNmZvcm1hdD1wbmdcdTAwMjZzdGlja2VyX2Zvcm1hdD0ud2VicCIsImxvZ2luX3R5cGUiOiJsYXJrIiwidGVuYW50X2tleSI6IjczNjU4OGM5MjYwZjE3NWQiLCJzYWFzX3RlbmFudF9rZXkiOiJCeXRlRGFuY2UiLCJkZXBfaWRzIjoiIiwiZW1wbG95ZWVJZCI6IiJ9LCJleHAiOjE2Mjg0NzgzNDV9.YtyvFtTntHWuyh0PosqsRnL90r5VKPRhCMVwn-o_Cds' \
--header 'Content-Type: application/' \
--data-raw '{
"plugin_id": "MII_60F3CC30CF43C12C", // plugin_id
"state": "111" // 自定义状态码
}'
使用Cookie获取code
- 登录飞书项目,拿到飞书项目侧cookie。
- 构造登录curl。
curl --location --request POST 'https://{平台域名}/bff/v2/authen/v1/auth_code' \
--header 'cookie: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Im5pY2tuYW1lIjoi5p2O5oCh5ZCbIiwiZW1haWwiOiJsaXlpanVuLmxhcmtAYnl0ZWRhbmNlLmNvbSIsInVzZXJuYW1lIjoibGl5aWp1bi5sYXJrIiwidXNlcl90eXBlIjowLCJhdmF0YXJfdXJsIjoiaHR0cHM6Ly9zMy1mcy5wc3RhdHAuY29tL3N0YXRpYy1yZXNvdXJjZS92MS9hYzgzNGMzYS1hNjFjLTQ2OTEtYjFiMy00MzM5ZjhiNjRhZWd-P2ltYWdlX3NpemU9NzJ4NzJcdTAwMjZjdXRfdHlwZT1cdTAwMjZxdWFsaXR5PVx1MDAyNmZvcm1hdD1wbmdcdTAwMjZzdGlja2VyX2Zvcm1hdD0ud2VicCIsImxvZ2luX3R5cGUiOiJsYXJrIiwidGVuYW50X2tleSI6IjczNjU4OGM5MjYwZjE3NWQiLCJzYWFzX3RlbmFudF9rZXkiOiJCeXRlRGFuY2UiLCJkZXBfaWRzIjoiIiwiZW1wbG95ZWVJZCI6IiJ9LCJleHAiOjE2Mjg0NzgzNDV9.YtyvFtTntHWuyh0PosqsRnL90r5VKPRhCMVwn-o_Cds' \
--header 'Content-Type: application/' \
--data-raw '{
"plugin_id": "MII_60F3CC30CF43C12C", // plugin_id
"state": "111" // 自定义状态码
}'
三、获取用户身份
使用第三步获得的code,以及plugin_token(获取方式见plugin_token获取流程)换取user_plugin_token。要注意,code的有效期为5分钟,且仅能使用一次。
请求:
基本信息 | |
HTTP URL | https://{平台域名}/bff/v2/authen/user_plugin_token |
HTTP Method | POST |
HTTP Content-Type | application/ |
请求头:
参数 | 类型 | 是否必填 | 示例 | 说明 |
X-Plugin-Token | string | 是 | p-24af8f8f-290f-4fc7-86e1-b592e46dee43 | plugin_token |
请求体:
参数 | 类型 | 是否必填 | 示例 | 说明 |
code | string | 是 | 842ne8f2912044ce8dead5a10e93bfb3 | 预授权code |
grant_type | string | 是 | authorization_code | 授权方式,固定为authorization_code |
响应体:
data | ||
参数 | 类型 | 说明 |
token | string | token值 |
expire_time | int | 失效时间 |
refresh_token | string | 刷新token |
refresh_token_expire_time | int | 刷新token过期时间 |
user_key | string | 飞书项目侧用户唯一id |
saas_tenant_key | string | 飞书项目侧租户唯一id |
error | ||
参数 | 类型 | 说明 |
code | int | 错误码,非0表示失败 |
msg | string | 错误描述 |
curl 示例:
curl --location --request POST 'https://{平台域名}/bff/v2/authen/user_plugin_token' \
--header 'X-Plugin-Token: p-9ca2de28-d5c0-4084-82ca-e74f73911aaf' \
--header 'Content-Type: application/' \
--data-raw '{
"code": "c942f20e7d9241ef91ee4c0281fd3c29",
"grant_type": "authorization_code"
}'
返回:
{
"data": {
"token": "u-717d4bf7-4c97-44e1-82ef-8afb3e164177",
"expire_time": 7199,
"refresh_token": "36146486-6432-425e-ac92-1e53f5f0388a",
"refresh_token_expire_time": 1209599,
"saas_tenant_key": "Bytedance",
"user_key": "liyijun.lark"
},
"error": {
"code": 0,
"msg": "success"
}
}
刷新Token
目前刷新token仅支持刷新user_plugin_token。原因是user_plugin_token的获取流程比较长,所以提供了一个刷新的机制。而plugin_token是不需要刷新的,过期之后重新获取就好。
请求:
基本信息 | |
HTTP URL | https://{平台域名}/bff/v2/authen/refresh_token |
HTTP Method | POST |
HTTP Content-Type | application/ |
请求头:
参数 | 类型 | 是否必填 | 示例 | 说明 |
X-Plugin-Token | string | 是 | p-24af8f8f-290f-4fc7-86e1-b592e46dee43 | plugin_token |
请求体:
参数 | 类型 | 是否必填 | 示例 | 说明 |
refresh_token | string | 是 | 53af8f8f-540f-4fc7-86e1-b592e46dee43 | 刷新token |
type | int | 是 | 1 | 要刷新的token类型,目前固定填1 |
响应体:
data | ||
参数 | 类型 | 说明 |
token | string | token值 |
expire_time | int | 失效时间 |
refresh_token | string | 刷新token |
refresh_token_expire_time | int | 刷新token过期时间 |
error | ||
参数 | 类型 | 说明 |
code | int | 错误码,非0表示失败 |
msg | string | 错误描述 |
curl 示例:
curl --location --request POST 'https://{平台域名}/bff/v2/authen/refresh_token' \
--header 'X-Plugin-Token: p-9ca2de28-d5c0-4084-82ca-e74f73911aaf' \
--header 'Content-Type: application/' \
--data-raw '{
"refresh_token": "b7817f244e1142888fb214596878998a",
"type": 1
}'
返回:
{
"data": {
"token": "u-717d4bf7-4c97-44e1-82ef-8afb3e164177",
"expire_time": 7199,
"refresh_token": "36146486-6432-425e-ac92-1e53f5f0388a",
"refresh_token_expire_time": 1209599,
},
"error": {
"code": 0,
"msg": "success"
}
}
错误码
业务错误码 | msg | 备注 |
10100 | server internal error | 服务内部错误 |
10010 | request parameter illegal | 请求参数不合法 |
10011 | request parameter type error | 请求参数类型错误 |
10012 | request parameter value error | 请求参数取值错误 |
10021 | token not exist | token/cookie不存在 |
10022 | token expire | token/cookie过期 |
10201 | get plugin_token fail | 获取plugin_token失败 |
10202 | get user plugin token fail | 获取user_plugin_token失败 |
10204 | wrong plugin secret | 错误的插件秘钥 |
10205 | get auth code fail | 获取预授权code失败 |
10209 | refresh token fail | 刷新token失败 |
10210 | code invalid | 无效的预授权code |
10211 | wrong plugin id | 错误的插件id |
10214 | plugin_token is nil | plugin_token 为空 |
10215 | plugin_token check fail | plugin_token校验失败 |
10223 | plugin_token invalid | plugin token无效 |
10224 | session key is invalid | 无效的sessionkey |