获取 access_token
获取应用级凭证 access_token。第三方应用后端使用 client_credentials 模式换取令牌,用于调用成员、组织架构、企业信息及机器人等开放接口。
接口信息
| 项目 | 说明 |
|---|---|
| 接口名称 | 获取 access_token |
| 请求方式 | POST |
| 请求地址 | https://{gateway_host}/auth/v1/oauth/token |
| 数据格式 | application/json |
| 鉴权方式 | 无(使用应用凭据换取) |
| 跨域 | 支持浏览器跨域;不返回 Access-Control-Allow-Credentials。App Secret 仍不得下发到浏览器 |
前置条件
- 应用已在管理后台「内部应用」中创建并发布。
- 已在应用详情「凭证与基础信息」中获取
AppId(即client_id)和AppSecret(即client_secret)。 AppSecret仅保存在应用后端,严禁下发至前端或客户端。
请求参数
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
Content-Type | 是 | 固定为 application/json |
请求体
{
"client_id": "app_10001",
"client_secret": "link_xxxxxxxxx",
"grant_type": "client_credentials"
}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
client_id | string | 是 | 应用 AppId |
client_secret | string | 是 | 应用 AppSecret |
grant_type | string | 是 | 授权类型,固定为 client_credentials |
响应参数
成功响应(OAuth 标准 JSON 外壳,不含平台 {code,msg,data} 包装):
{
"access_token": "opaque-app-access-token",
"expires_in": 7200
}
| 字段 | 类型 | 说明 |
|---|---|---|
access_token | string | 应用级凭证令牌,默认有效期 7200 秒(2小时) |
expires_in | integer | 凭证剩余有效期,单位:秒 |
令牌使用规则
- 复用与缓存:
access_token在有效期内可重复使用,建议应用后端在本地集中缓存并提前(如剩余5分钟时)自动刷新,避免频繁请求该接口。 - 凭证隔离:
access_token是应用级凭证,不是用户登录态,不得放入 Cookie、不得下发给客户端,也不能当作业务系统自身的 Bearer Token。 - Secret 轮换:应用管理员在后台轮换
AppSecret后,旧密钥签发的所有access_token立即失效,需重新请求本接口获取新令牌。 - 携带方式:调用开放接口时,推荐通过请求头
Authorization: Bearer <access_token>携带,部分接口亦支持 Query 参数?access_token=<access_token>。
错误码说明
换取令牌失败时使用 HTTP 状态码与 OAuth error 字段返回:
{
"error": "INVALID_CLIENT",
"error_description": "invalid client credentials"
}
| HTTP 状态码 | error 错误码 | 含义与排查建议 |
|---|---|---|
| 400 | INVALID_REQUEST | 请求格式不是合法的 JSON、grant_type 取值不为 client_credentials 或必填字段缺失 |
| 401 | INVALID_CLIENT | 应用不存在、已被停用/删除,或 client_id 与 client_secret 不匹配 |
| 500 | SERVER_ERROR | 服务端异常,请稍后重试 |
多语言调用示例
以下示例使用服务端调用方式;应用密钥和应用令牌不得下发到客户端。
Shell
curl -sS -X POST "https://{gateway_host}/auth/v1/oauth/token" \
-H "Content-Type: application/json" \
-d '{"client_id":"app_10001","client_secret":"link_xxxxxxxxx","grant_type":"client_credentials"}'
PHP
<?php
// 中文注释:生产环境应检查 HTTP 状态码和响应体,再映射业务错误。
$handle = curl_init('https://{gateway_host}/auth/v1/oauth/token');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"client_id":"app_10001","client_secret":"link_xxxxxxxxx","grant_type":"client_credentials"}',
CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($handle);
curl_close($handle);
Golang
package main
import (
"bytes"
"net/http"
)
func main() {
// 中文注释:令牌只在服务端请求中使用,并按接口约定携带。
request, _ := http.NewRequest(http.MethodPost, "https://{gateway_host}/auth/v1/oauth/token", bytes.NewBufferString(`{"client_id":"app_10001","client_secret":"link_xxxxxxxxx","grant_type":"client_credentials"}`))
request.Header.Set("Content-Type", "application/json")
response, _ := http.DefaultClient.Do(request)
defer response.Body.Close()
}
C++
#include <curl/curl.h>
int main() {
// 中文注释:生产环境应启用 TLS 校验并处理 HTTP 错误。
CURL* handle = curl_easy_init();
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(handle, CURLOPT_URL, "https://{gateway_host}/auth/v1/oauth/token");
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, R"({"client_id":"app_10001","client_secret":"link_xxxxxxxxx","grant_type":"client_credentials"})");
const CURLcode result = curl_easy_perform(handle);
curl_slist_free_all(headers);
curl_easy_cleanup(handle);
return result == CURLE_OK ? 0 : 1;
}