获取用户信息
本文档介绍如何使用访问令牌获取用户信息。
API 接口
GET /api/OAuth2/UserInfo
请求参数
Header 参数
| 参数 | 必须 | 类型 | 说明 |
|---|---|---|---|
| Authorization | 是 | string | 访问令牌,格式:Bearer {ACCESS_TOKEN} |
| Content-Type | 是 | string | 固定值:application/json |
请求示例
HTTP 请求
GET /api/OAuth2/UserInfo HTTP/1.1
Host: your-platform.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
cURL 请求
curl -X GET "https://platform.com/api/OAuth2/UserInfo" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json"
响应格式
成功响应
{
"success": true,
"data": {
"sub": "d66c2f4f-db75-49bf-ad4d-515868b59e7f",
"email": "zhangsan@example.com",
"name": "张三",
"number": "zhangsan",
"phone": "13800138000"
},
"total": 0,
"action": 0,
"code": 200,
"message": "操作成功",
"moreMessage": null
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| sub | string | 用户 ID,唯一标识 |
| name | string | 用户名 |
| string | 邮箱地址 | |
| number | string | 编号 |
| phone | string | 手机号码 |
错误响应
{
"success": false,
"data": null,
"total": 0,
"action": 1,
"code": 510,
"message": "操作失败",
"moreMessage": "访问令牌无效或已过期"
}
代码示例
JavaScript
// 配置
const PLATFORM_URL = 'https://platform.com';
// 获取用户信息
async function getUserInfo(accessToken) {
const response = await fetch(
`${PLATFORM_URL}/api/OAuth2/UserInfo`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
const result = await response.json();
if (result.success && result.data) {
return result.data;
} else {
throw new Error(result.moreMessage || '获取用户信息失败');
}
}
// 使用示例
const accessToken = sessionStorage.getItem('access_token');
getUserInfo(accessToken)
.then(userInfo => {
console.log('用户 ID:', userInfo.user_id);
console.log('用户名:', userInfo.username);
console.log('邮箱:', userInfo.email);
console.log('姓名:', userInfo.name);
console.log('手机号:', userInfo.phone);
// 显示用户信息
displayUserInfo(userInfo);
})
.catch(error => {
console.error('错误:', error.message);
// 令牌无效,重新授权
redirectToAuth();
});
// 显示用户信息
function displayUserInfo(userInfo) {
document.getElementById('user-name').textContent = userInfo.name;
document.getElementById('user-email').textContent = userInfo.email;
document.getElementById('user-phone').textContent = userInfo.phone;
}
Python
import requests
# 配置
PLATFORM_URL = 'https://platform.com'
# 获取用户信息
def get_user_info(access_token):
url = f"{PLATFORM_URL}/api/OAuth2/UserInfo"
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
response = requests.get(url, headers=headers)
result = response.json()
if result.get('success') and result.get('data'):
return result['data']
else:
raise Exception(result.get('moreMessage', '获取用户信息失败'))
# 使用示例
access_token = 'your_access_token'
try:
user_info = get_user_info(access_token)
print(f"用户 ID: {user_info['user_id']}")
print(f"用户名: {user_info['username']}")
print(f"邮箱: {user_info['email']}")
print(f"姓名: {user_info['name']}")
print(f"手机号: {user_info['phone']}")
except Exception as e:
print(f"错误: {str(e)}")
# 令牌无效,重新授权
# redirect_to_auth()
用户信息字段
user_id(用户 ID)
- 类型:string
- 说明:用户的唯一标识符
- 格式:GUID 格式,如:
d66c2f4f-db75-49bf-ad4d-515868b59e7f - 用途:用于唯一标识用户,可作为用户主键
username(用户名)
- 类型:string
- 说明:用户的登录用户名
- 格式:字母、数字、下划线组合
- 用途:用于显示用户标识
email(邮箱)
- 类型:string
- 说明:用户的邮箱地址
- 格式:标准 邮箱格式
- 用途:可用于发送通知或联系方式
name(姓名)
- 类型:string
- 说明:用户的真实姓名
- 格式:中文或英文名称
- 用途:显示用户姓名,提供更友好的展示
phone(手机号)
- 类型:string
- 说明:用户的手机号码
- 格式:11 位手机号
- 用途:可用于发送短信通知或联系方式
完整流程示例
完整的 OAuth 2.0 流程
// 完整的 OAuth 2.0 流程示例
class OAuth2Client {
constructor(config) {
this.clientId = config.clientId;
this.clientSecret = config.clientSecret;
this.redirectUri = config.redirectUri;
this.platformUrl = config.platformUrl;
this.tenantId = config.tenantId;
}
// 生成随机 state
generateState() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
// 构造授权链接
buildAuthUrl() {
const state = this.generateState();
sessionStorage.setItem('oauth_state', state);
const params = new URLSearchParams({
client_id: this.clientId,
redirect_uri: this.redirectUri,
response_type: 'code',
scope: 'basic',
state: state
});
return `${this.platformUrl}/connect/oauth2/authorize?${params}`;
}
// 获取访问令牌
async getAccessToken(code) {
const params = new URLSearchParams({
client_id: this.clientId,
secret: this.clientSecret,
code: code
});
const response = await fetch(
`${this.platformUrl}/api/OAuth2/Token?${params}`,
{
headers: {
'X-Tenant-Id': this.tenantId
}
}
);
const result = await response.json();
if (result.code === 200 && result.data) {
// 存储令牌
sessionStorage.setItem('access_token', result.data.access_token);
sessionStorage.setItem('token_expires_at',
Date.now() + result.data.expires_in * 1000);
return result.data;
} else {
throw new Error(result.moreMessage || '获取访问令牌失败');
}
}
// 获取用户信息
async getUserInfo() {
const accessToken = sessionStorage.getItem('access_token');
if (!accessToken) {
throw new Error('未找到访问令牌');
}
const response = await fetch(
`${this.platformUrl}/api/OAuth2/UserInfo`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
const result = await response.json();
if (result.success && result.data) {
return result.data;
} else {
throw new Error(result.moreMessage || '获取用户信息失败');
}
}
// 处理回调
async handleCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
// 验证 state
const expectedState = sessionStorage.getItem('oauth_state');
if (state !== expectedState) {
throw new Error('State 验证失败');
}
// 获取访问令牌
const tokenData = await this.getAccessToken(code);
// 获取用户信息
const userInfo = await this.getUserInfo();
return {
token: tokenData,
user: userInfo
};
}
}
// 使用示例
const client = new OAuth2Client({
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'https://your-app.com/callback',
platformUrl: 'https://platform.com',
tenantId: 'your_tenant_id'
});
// 发起授权
// window.location.href = client.buildAuthUrl();
// 处理回调
// client.handleCallback()
// .then(result => {
// console.log('用户信息:', result.user);
// })
// .catch(error => {
// console.error('错误:', error.message);
// });
错误处理
常见错误
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
| 访问令牌无效或已过期 | token 无效或过期 | 重新获取访问令牌 |
| 未授权访问 | token 未提供或格式错误 | 检查 Authorization header |
| 用户不存在 | 用户已被删除 | 检查用户状态 |
错误处理示例
async function getUserInfo(accessToken) {
try {
const response = await fetch(
`${PLATFORM_URL}/api/OAuth2/UserInfo`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
const result = await response.json();
if (result.success && result.data) {
return result.data;
} else {
// 处理业务错误
const errorMsg = result.moreMessage || result.message || '未知错误';
throw new Error(errorMsg);
}
} catch (error) {
// 处理网络错误或其他异常
console.error('获取用户信息失败:', error);
throw error;
}
}
注意事项
-
令牌有效期
- 确保访问令牌未过期
- 在令牌过期前及时刷新
-
安全传输
- 使用 HTTPS 传输数据
- 不要在 URL 中传递访问令牌
-
数据安全
- 妥善处理用户信息
- 不要在客户端暴露敏感信息
常见问题
Q1: 提示"访问令牌无效或已过期"?
原因:访问令牌已过期或无效。
解决:
- 检查令牌是否正确
- 检查令牌是否过期
- 重新获取访问令牌
Q2: 如何更新用户信息?
方法:
- 用户信息会实时更新
- 每次调用 API 都会返回最新的用户信息
- 建议缓存用户信息,但定期更新