// ========================================== // 🔴 第一步:在这里填入你的核心保密信息 // ========================================== const CONFIG = { ACCESS_KEY_ID: 'SXa3kjfkal93TlxBQNdQP3Du9zrrHDsc', // 例如:VMOSAK123456 SECRET_ACCESS_KEY: 'Fr1NpI8h1ZAr93u7WXPj0xGH', // 例如:VMOSSKabcdefg PAD_CODE: 'ACP250501X5J61Z9', // 例如:AC32010230001 HOST: 'openapi-hk.armcloud.net', // 接口域名(香港节点) SERVICE: 'armcloud-paas', ALGORITHM: 'HMAC-SHA256', }; // ========================================== // 核心路由与请求处理 // ========================================== export default { async fetch(request, env, ctx) { const url = new URL(request.url); // 当用户访问根目录时,先去拿 Token,然后组装网页返回 if (url.pathname === '/') { try { // 1. 自动获取最新的 STS Token const token = await fetchStsToken(); // 2. 将拿到的 Token 注入 HTML 并返回给浏览器 return new Response(generateHTML(token, CONFIG.PAD_CODE, CONFIG.HOST), { headers: { 'content-type': 'text/html;charset=UTF-8', 'Access-Control-Allow-Origin': '*', // 允许所有来源跨域 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS' }, }); } catch (error) { return new Response(`获取 Token 失败,请检查 AK/SK 配置: ${error.message}`, { status: 500 }); } } return new Response('Not Found', { status: 404 }); }, }; // ========================================== // 底层加密与 API 请求逻辑 (翻译自你提供的文档) // ========================================== async function fetchStsToken() { const apiUrl = `https://${CONFIG.HOST}/vcpcloud/api/padApi/stsTokenByPadCode`; // 准备请求体 (Body) const requestBody = JSON.stringify({ padCode: CONFIG.PAD_CODE }); // 获取当前 UTC 时间 const now = new Date(); const xDate = now.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z'; // 格式: YYYYMMDDTHHMMSSZ const shortXDate = xDate.substring(0, 8); // 格式: YYYYMMDD const contentType = "application/json"; const signedHeaders = "content-type;host;x-content-sha256;x-date"; const credentialScope = `${shortXDate}/${CONFIG.SERVICE}/request`; // 1. 计算 Body 的 SHA256 哈希 const bodyHashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(requestBody)); const xContentSha256 = bufferToHex(bodyHashBuffer); // 2. 构建规范请求字符串 (CanonicalRequest) const canonicalString = [ `host:${CONFIG.HOST}`, `x-date:${xDate}`, `content-type:${contentType}`, `signedHeaders:${signedHeaders}`, `x-content-sha256:${xContentSha256}` ].join('\n'); // 3. 计算规范请求的 SHA256 const canonicalHashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(canonicalString)); const hashedCanonicalString = bufferToHex(canonicalHashBuffer); // 4. 构建待签名字符串 (StringToSign) const stringToSign = [ CONFIG.ALGORITHM, xDate, credentialScope, hashedCanonicalString ].join('\n'); // 5. 生成派生签名密钥 (SigningKey) const kDate = await hmacSHA256(new TextEncoder().encode(CONFIG.SECRET_ACCESS_KEY), shortXDate); const kService = await hmacSHA256(kDate, CONFIG.SERVICE); const signKey = await hmacSHA256(kService, "request"); // 6. 最终计算 Signature const signatureBuffer = await hmacSHA256(signKey, stringToSign); const signature = bufferToHex(signatureBuffer); // 7. 组装 Authorization 头部 const authorization = `${CONFIG.ALGORITHM} Credential=${CONFIG.ACCESS_KEY_ID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`; // 8. 发送真实的 HTTP 请求获取 Token const response = await fetch(apiUrl, { method: 'POST', headers: { 'content-type': contentType, 'x-date': xDate, 'x-host': CONFIG.HOST, 'authorization': authorization }, body: requestBody }); const result = await response.json(); if (result.code === 200 && result.data && result.data.token) { return result.data.token; } else { throw new Error(JSON.stringify(result)); } } // 辅助函数:HMAC-SHA256 算法实现 async function hmacSHA256(keyBuffer, message) { const key = await crypto.subtle.importKey( "raw", keyBuffer, { name: "HMAC", hash: "SHA-256" }, false, ["sign"] ); const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message)); return new Uint8Array(signature); } // 辅助函数:将 Buffer 转成 16 进制字符串 function bufferToHex(buffer) { return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join(''); } // ========================================== // 极简前端界面 (H5 SDK) // ========================================== function generateHTML(token, padCode, host) { return `