跳到主要内容

获取访问令牌

本文档介绍如何使用授权码换取访问令牌(Access Token)。

API 接口​

POST /api/OAuth2/Token

请求参数​

Header 参数​

参数必须类型说明
Content-Type是string固定值:application/json
X-Tenant-Id是string租户 ID

Body 参数​

参数必须类型说明
client_id是string客户端 ID
secret是string客户端密钥
code是string授权码

请求示例​

HTTP 请求​

POST /api/OAuth2/Token HTTP/1.1
Host: your-platform.com
Content-Type: application/json
X-Tenant-Id: develop

{
"client_id": "1c1e3458cd4344fbbeea2a8103d6ab44",
"secret": "Pr#2_-vVNCN8joLOJ#kXyzZ2*UBJh!2V",
"code": "4bed401590f94bd1a76c0a2e1d5b5788"
}

cURL 请求​

curl -X POST "https://platform.com/api/OAuth2/Token" \
-H "Content-Type: application/json" \
-H "X-Tenant-Id: your_tenant_id" \
-d '{
"client_id": "your_client_id",
"secret": "your_client_secret",
"code": "your_code"
}'

响应格式​

成功响应​

{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 7200
},
"total": 0,
"action": 0,
"code": 200,
"message": "操作成功",
"moreMessage": null
}

响应字段说明​

字段类型说明
access_tokenstring访问令牌,用于调用平台接口
token_typestring令牌类型,固定为 Bearer
expires_innumber令牌有效期(秒)

错误响应​

{
"data": null,
"total": 0,
"action": 1,
"code": 510,
"message": "操作失败",
"moreMessage": "授权码无效或已过期"
}

代码示例​

JavaScript​

// 配置
const CLIENT_ID = 'your_client_id';
const CLIENT_SECRET = 'your_client_secret';
const PLATFORM_URL = 'https://platform.com';
const TENANT_ID = 'your_tenant_id';

// 使用授权码换取访问令牌
async function getAccessToken(code) {
const response = await fetch(
`${PLATFORM_URL}/api/OAuth2/Token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Tenant-Id': TENANT_ID
},
body: JSON.stringify({
client_id: CLIENT_ID,
secret: CLIENT_SECRET,
code: code
})
}
);

const result = await response.json();

if (result.code === 200 && result.data) {
return result.data;
} else {
throw new Error(result.moreMessage || '获取访问令牌失败');
}
}

// 使用示例
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');

getAccessToken(code)
.then(tokenData => {
console.log('访问令牌:', tokenData.access_token);
console.log('令牌类型:', tokenData.token_type);
console.log('有效期:', tokenData.expires_in, '秒');
})
.catch(error => {
console.error('错误:', error.message);
});

Python​

import requests

# 配置
CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
PLATFORM_URL = 'https://platform.com'
TENANT_ID = 'your_tenant_id'

# 使用授权码换取访问令牌
def get_access_token(code):
url = f"{PLATFORM_URL}/api/OAuth2/Token"

headers = {
'Content-Type': 'application/json',
'X-Tenant-Id': TENANT_ID
}

data = {
'client_id': CLIENT_ID,
'secret': CLIENT_SECRET,
'code': code
}

response = requests.post(url, json=data, headers=headers)
result = response.json()

if result.get('code') == 200 and result.get('data'):
return result['data']
else:
raise Exception(result.get('moreMessage', '获取访问令牌失败'))

# 使用示例
code = 'your_authorization_code'

try:
token_data = get_access_token(code)
print(f"访问令牌: {token_data['access_token']}")
print(f"令牌类型: {token_data['token_type']}")
print(f"有效期: {token_data['expires_in']} 秒")
except Exception as e:
print(f"错误: {str(e)}")

令牌管理​

存储令牌​

访问令牌需要妥善存储,避免泄露:

// 存储到会话存储(推荐)
sessionStorage.setItem('access_token', tokenData.access_token);
sessionStorage.setItem('token_expires_at', Date.now() + tokenData.expires_in * 1000);

// 或者存储到内存中
let accessToken = {
token: tokenData.access_token,
expiresAt: Date.now() + tokenData.expires_in * 1000
};

检查令牌有效性​

// 检查令牌是否过期
function isTokenExpired() {
const expiresAt = parseInt(sessionStorage.getItem('token_expires_at'));
return Date.now() >= expiresAt;
}

// 获取有效的访问令牌
function getValidToken() {
if (isTokenExpired()) {
// 令牌已过期,需要重新授权
sessionStorage.removeItem('access_token');
sessionStorage.removeItem('token_expires_at');
return null;
}
return sessionStorage.getItem('access_token');
}

使用令牌调用接口​

// 使用访问令牌调用 API
async function callApi(url, options = {}) {
const token = getValidToken();

if (!token) {
throw new Error('访问令牌无效或已过期');
}

const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
...options.headers
};

const response = await fetch(url, {
...options,
headers
});

return response.json();
}

错误处理​

常见错误​

错误信息原因解决方案
授权码无效或已过期code 已使用或超时重新获取授权码
客户端 ID 无效client_id 错误检查 client_id 是否正确
客户端密钥错误secret 错误检查 secret 是否正确
租户 ID 无效X-Tenant-Id 错误检查租户 ID 是否正确

错误处理示例​

async function getAccessToken(code) {
try {
const response = await fetch(
`${PLATFORM_URL}/api/OAuth2/Token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Tenant-Id': TENANT_ID
},
body: JSON.stringify({
client_id: CLIENT_ID,
secret: CLIENT_SECRET,
code: code
})
}
);

const result = await response.json();

if (result.code === 200 && result.data) {
return result.data;
} else {
// 处理业务错误
const errorMsg = result.moreMessage || result.message || '未知错误';
throw new Error(errorMsg);
}
} catch (error) {
// 处理网络错误或其他异常
console.error('获取访问令牌失败:', error);
throw error;
}
}

注意事项​

  1. 授权码有效期

    • 授权码(code)有效期很短,通常只有几分钟
    • 获取到 code 后应立即换取 token
    • 每个 code 只能使用一次
  2. 访问令牌有效期

    • 访问令牌有效期通常为 2 小时(7200 秒)
    • 在令牌即将过期时需要重新授权
    • 建议在令牌过期前 5 分钟重新获取
  3. 安全建议

    • 不要在客户端代码中暴露 Client Secret
    • 使用 HTTPS 传输数据
    • 妥善存储访问令牌

常见问题​

Q1: Token 获取失败?​

原因:可能是 code 过期或参数错误。

解决:

  1. 检查 code 是否正确且未过期
  2. 检查 client_id 和 secret 是否正确
  3. 检查租户 ID 是否正确

Q2: 如何判断令牌是否过期?​

方法:

  1. 记录令牌的过期时间(expires_at = 当前时间 + expires_in)
  2. 每次使用前检查当前时间是否超过过期时间
  3. 建议提前 5 分钟刷新令牌

Q3: 令牌过期后如何处理?​

处理方式:

  1. 清除本地存储的令牌
  2. 重新引导用户授权
  3. 获取新的授权码和访问令牌

下一步​