Files
ruoyi-java/doc/腾讯文档API鉴权修复指南.md
2025-11-06 02:32:27 +08:00

241 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 腾讯文档 API 鉴权修复指南
## 关键发现
根据腾讯文档官方 API 文档,发现了之前鉴权方式的重大错误:
### 正确的鉴权方式
腾讯文档 V3 API 需要**三个请求头**进行鉴权:
```http
Access-Token: {访问令牌}
Client-Id: {应用ID}
Open-Id: {开放平台用户ID}
```
**而不是**
```http
Authorization: Bearer {访问令牌} ❌ 错误!
```
## 推荐方案:使用应用级账号 Token
### 什么是应用级账号 Token
- 不需要用户授权流程
- 直接使用 `client_id``client_secret` 获取
- 响应包含所有需要的信息
### API 接口
**请求:**
```http
GET https://docs.qq.com/oauth/v2/app-account-token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET
```
**响应:**
```json
{
"access_token": "ACCESSTOKENEXAMPLE",
"token_type": "Bearer",
"refresh_token": "REFRESHTOKENEXAMPLE",
"expires_in": 259200,
"scope": "scope.file.editable,scope.folder.creatable",
"user_id": "bcb50c8a4b724d86bbcf6fc64c5e2b22"
}
```
### 字段映射
| 响应字段 | 对应请求头 | 说明 |
|---------|-----------|------|
| `access_token` | `Access-Token` | 访问令牌 |
| 请求参数 `client_id` | `Client-Id` | 应用ID |
| `user_id` | `Open-Id` | 开放平台用户ID关键 |
## 完整的 API 调用流程
### 步骤1获取应用级账号 Token
```java
JSONObject tokenInfo = TencentDocApiUtil.getAppAccountToken(appId, appSecret);
String accessToken = tokenInfo.getString("access_token");
String openId = tokenInfo.getString("user_id"); // 这就是 Open-Id
String clientId = appId; // Client-Id 就是 appId
```
### 步骤2调用业务 API
```java
// 设置请求头
conn.setRequestProperty("Access-Token", accessToken);
conn.setRequestProperty("Client-Id", clientId);
conn.setRequestProperty("Open-Id", openId);
conn.setRequestProperty("Content-Type", "application/json");
```
### 步骤3发送请求
```http
GET https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/A1:Z100
Access-Token: ACCESSTOKENEXAMPLE
Client-Id: YOUR_CLIENT_ID
Open-Id: bcb50c8a4b724d86bbcf6fc64c5e2b22
Content-Type: application/json
```
## 代码修改方案
### 方案 A简单封装推荐
在 Service 层创建一个包装类来管理鉴权信息:
```java
public class TencentDocAuth {
private String accessToken;
private String clientId;
private String openId;
private long expiresAt;
// 获取或刷新 Token
public static TencentDocAuth getAuth(String appId, String appSecret) {
JSONObject tokenInfo = TencentDocApiUtil.getAppAccountToken(appId, appSecret);
TencentDocAuth auth = new TencentDocAuth();
auth.accessToken = tokenInfo.getString("access_token");
auth.openId = tokenInfo.getString("user_id");
auth.clientId = appId;
auth.expiresAt = System.currentTimeMillis() + tokenInfo.getIntValue("expires_in") * 1000;
return auth;
}
// Getters...
}
```
### 方案 B修改现有方法签名
修改 `callApi` 方法,添加必要的参数:
```java
public static JSONObject callApi(String accessToken, String clientId, String openId,
String apiUrl, String method, String body) {
conn.setRequestProperty("Access-Token", accessToken);
conn.setRequestProperty("Client-Id", clientId);
conn.setRequestProperty("Open-Id", openId);
// ...
}
```
然后更新所有调用此方法的地方。
## 实现步骤
### 1. 添加获取应用级账号 Token 的方法 ✅
已在 `TencentDocApiUtil.java` 中添加:
```java
public static JSONObject getAppAccountToken(String appId, String appSecret)
```
### 2. 修改 callApi 方法 ✅
已更新为:
```java
public static JSONObject callApi(String accessToken, String clientId, String openId,
String apiUrl, String method, String body)
```
### 3. 更新所有调用点(待完成)
需要更新以下方法:
- `readSheetData()`
- `writeSheetData()`
- `appendSheetData()`
- `getFileInfo()`
- `getSheetList()`
以及所有调用这些方法的 Service 类。
## 测试验证
### 1. 获取应用级账号 Token
```java
JSONObject tokenInfo = TencentDocApiUtil.getAppAccountToken(
"YOUR_CLIENT_ID",
"YOUR_CLIENT_SECRET"
);
System.out.println("Access Token: " + tokenInfo.getString("access_token"));
System.out.println("Open-Id: " + tokenInfo.getString("user_id"));
```
### 2. 调用表格 API
```java
String accessToken = tokenInfo.getString("access_token");
String clientId = "YOUR_CLIENT_ID";
String openId = tokenInfo.getString("user_id");
JSONObject result = TencentDocApiUtil.readSheetData(
accessToken, clientId, openId,
"YOUR_FILE_ID", "SHEET_ID", "A1:Z10",
"https://docs.qq.com/openapi/spreadsheet/v3"
);
```
## 注意事项
### 1. Token 有效期
应用级账号 Token 默认有效期为 3 天259200秒需要定期刷新。
### 2. 存储安全
- `client_secret` 必须保密
- Token 应该缓存并在过期前刷新
- 不要在日志中打印完整的 Token
### 3. 权限范围
应用级账号的权限取决于申请时的 scope
- `scope.sheet` - 读取表格
- `scope.sheet.editable` - 编辑表格
- `scope.file.editable` - 编辑文件
- `scope.folder.creatable` - 创建文件夹
## 错误排查
### 401 Unauthorized
- 检查 Access-Token 是否正确
- 检查 Token 是否过期
- 检查是否包含所有三个请求头
### 403 Forbidden
- 检查应用是否有相应的权限 (scope)
- 检查 Open-Id 是否正确
### 404 Not Found
- 检查 URL 路径是否正确
- 确认基础 URL 为 `https://docs.qq.com/openapi/spreadsheet/v3`
- 确认路径格式为 `/files/{fileId}/...`
## 参考文档
- [批量更新接口](https://docs.qq.com/open/document/app/openapi/v3/sheet/batchUpdate.html)
- [获取应用级账号 Token](https://docs.qq.com/open/document/app/oauth2/app-account-token.html)
- [请求头部说明](https://docs.qq.com/open/document/app/openapi/v3/)
---
**更新时间**2025-11-05
**状态**:部分完成,需要更新所有调用点