基本类似的代码,请求获取公司信息和应用信息都是正常的,但是请求drive相关的接口都会报错
{
code: 400000003,
message: kso: PermissionDenied access_token verify err: invalid_scope {"desc":"The requested scope is invalid, unknown, or malformed. The request scopes 'kso.drive.readwrite' has not been granted or is not allowed to be requested."}, cause: , desc: The requested scope is invalid, unknown, or malformed. The request scopes 'kso.drive.readwrite' has not been granted or is not allowed to be requested., tip:
}
测试代码如下:
const axios = require("axios");
const crypto = require("crypto");
const BASE_URL = "https://openapi.wps.cn";
const APP_ID = ""; // 请替换为实际的 APPID
const APP_SECRET_KEY = ""; // 请替换为实际的 APPKEY
/**
* 生成 RFC1123 格式的时间字符串
* @returns {string} RFC1123 格式的日期字符串
*/
function getRFC1123Date() {
return new Date().toUTCString();
}
/**
* 获取 Access Token
* @returns {Promise} 返回 access_token
*/
async function getAccessToken() {
const url = `${BASE_URL}/oauth2/token`;
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
const body = new URLSearchParams({
grant_type: "client_credentials",
client_id: APP_ID,
client_secret: APP_SECRET_KEY,
}).toString();
try {
const response = await axios.post(url, body, { headers });
return response.data.access_token;
} catch (error) {
console.error(
"Error fetching access token:",
error.response ? error.response.data : error.message
);
throw error;
}
}
/**
* 生成 KSO-1 签名
* @param {string} method 请求方法 (GET, POST, etc.)
* @param {string} requestUri 请求 URI (包含 query 参数)
* @param {string} contentType 请求的 Content-Type
* @param {string} ksoDate 请求的 X-Kso-Date (RFC1123 格式时间)
* @param {string} requestBody 请求体字符串 (如果没有,传空字符串 "")
* @returns {string} 计算后的签名字符串
*/
function generateSignature(
method,
requestUri,
contentType,
ksoDate,
requestBody
) {
const requestBodyHash = requestBody
? crypto.createHash("sha256").update(requestBody, "utf8").digest("hex")
: "";
const stringToSign = `KSO-1${method}${requestUri}${contentType}${ksoDate}${requestBodyHash}`;
return crypto
.createHmac("sha256", APP_SECRET_KEY)
.update(stringToSign, "utf8")
.digest("hex");
}
/**
* 获取本企业信息
* @param {string} accessToken 授权 token
* @returns {Promise} 企业信息数据
*/
async function getCompanyInfo(accessToken) {
const method = "GET";
const requestUri = "/v7/companies/current";
const contentType = "application/json";
const ksoDate = getRFC1123Date();
const requestBody = "";
const signature = generateSignature(
method,
requestUri,
contentType,
ksoDate,
requestBody
);
const authorizationHeader = `KSO-1 ${APP_ID}:${signature}`;
const headers = {
"Content-Type": contentType,
"X-Kso-Date": ksoDate,
"X-Kso-Authorization": authorizationHeader,
Authorization: `Bearer ${accessToken}`,
};
try {
const response = await axios.get(BASE_URL + requestUri, { headers });
return response.data;
} catch (error) {
console.error(
"Error fetching company info:",
error.response ? error.response.data : error.message
);
throw error;
}
}
/**
* 创建新的驱动盘
* @param {string} accessToken 授权 token
* @param {Object} driveData 驱动盘信息
* @returns {Promise} 新建驱动盘数据
*/
async function createDrive(accessToken, driveData) {
const method = "POST";
const requestUri = "/v7/drives/create";
const contentType = "application/json";
const ksoDate = getRFC1123Date();
const requestBody = JSON.stringify(driveData);
const signature = generateSignature(
method,
requestUri,
contentType,
ksoDate,
requestBody
);
const authorizationHeader = `KSO-1 ${APP_ID}:${signature}`;
const headers = {
"Content-Type": contentType,
"X-Kso-Date": ksoDate,
"X-Kso-Authorization": authorizationHeader,
Authorization: `Bearer ${accessToken}`,
};
try {
const response = await axios.post(BASE_URL + requestUri, requestBody, {
headers,
});
return response.data;
} catch (error) {
console.error(
"Error creating drive:",
error.response ? error.response.data : error.message
);
throw error;
}
}
/**
* 获取 WPS 盘列表
* @param {string} accessToken 授权 token
* @param {Object} params 请求参数
* @returns {Promise} 盘列表数据
*/
async function getDrives(accessToken, params) {
const method = "GET";
const requestUri = "/v7/drives";
const fullRequestUri =
requestUri + (params ? `?${new URLSearchParams(params).toString()}` : "");
const contentType = "application/json";
const ksoDate = getRFC1123Date();
const requestBody = "";
const signature = generateSignature(
method,
fullRequestUri,
contentType,
ksoDate,
requestBody
);
const authorizationHeader = `KSO-1 ${APP_ID}:${signature}`;
const headers = {
"Content-Type": contentType,
"X-Kso-Date": ksoDate,
"X-Kso-Authorization": authorizationHeader,
Authorization: `Bearer ${accessToken}`,
};
try {
const response = await axios.get(BASE_URL + fullRequestUri, { headers });
return response.data;
} catch (error) {
console.error(
"Error fetching drives:",
error.response ? error.response.data : error.message
);
throw error;
}
}
/**
* 获取应用信息
* @param {string} accessToken 授权 token
* @returns {Promise} 应用信息数据
*/
async function getApplicationInfo(accessToken) {
const method = "GET";
const requestUri = "/v7/developer/applications/current";
const contentType = "application/json";
const ksoDate = getRFC1123Date();
const requestBody = ""; // GET 请求没有请求体
// 生成 KSO-1 签名
const signature = generateSignature(
method,
requestUri,
contentType,
ksoDate,
requestBody
);
const authorizationHeader = `KSO-1 ${APP_ID}:${signature}`;
// 设置请求头
const headers = {
"Content-Type": contentType,
"X-Kso-Date": ksoDate,
"X-Kso-Authorization": authorizationHeader,
Authorization: `Bearer ${accessToken}`, // 认证头
};
try {
// 发送 GET 请求
const response = await axios.get(BASE_URL + requestUri, { headers });
return response.data;
} catch (error) {
console.error(
"Error fetching application info:",
error.response ? error.response.data : error.message
);
throw error;
}
}
// 主函数
async function main() {
let accessToken;
try {
accessToken = await getAccessToken();
console.log("Access Token:", accessToken);
} catch (error) {
console.error("Failed to retrieve access token.");
return;
}
try {
const companyInfo = await getCompanyInfo(accessToken);
console.log("Company Info:", JSON.stringify(companyInfo, null, 2));
} catch (error) {
console.error("Failed to retrieve company info.");
}
try {
const queryParams = {
// allotee_id: "",
allotee_type: "app", // user, group, app
page_size: 100,
with_ext_attrs: true,
};
const driveList = await getDrives(accessToken, queryParams);
console.log("Drive List:", JSON.stringify(driveList, null, 2));
} catch (error) {
console.error("Failed to retrieve drive list.");
}
// try {
// const newDriveData = {
// allotee_id: APP_ID,
// allotee_type: "app", // user, group, app
// name: "NewDriveName",
// description: "This is a test drive",
// // total_quota: 104857600, // 100MB
// // ext_attrs: [
// // {
// // name: "custom_attr",
// // value: "custom_value",
// // },
// // ],
// };
// const newDrive = await createDrive(accessToken, newDriveData);
// console.log("New Drive Created:", JSON.stringify(newDrive, null, 2));
// } catch (error) {
// console.error("Failed to create new drive.");
// }
try {
const appInfo = await getApplicationInfo(accessToken);
console.log("Application Info:", JSON.stringify(appInfo, null, 2));
} catch (error) {
console.error("Failed to retrieve application info.");
}
}
main();
输出结果