This commit is contained in:
wanghu
2026-09-02 10:23:24 +08:00
parent 5a414b14d2
commit ce436cbb32
117 changed files with 13768 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env node
// /oapi 签名票据生成器(对齐 yh-platform-net SignUtil.SignRequest / SignCanonical 协议)
//
// 协议:signature = Base64(HmacSHA256(METHOD + "\n" + path[?sortedQuery] + "\n" + timestamp, secret))
// - query 按 k=v 整体字典序排序后拼接参与签名
// - timestamp 为毫秒级 Unix 时间戳(服务端校验 5 分钟窗口)
//
// 用法:
// node scripts/oapi-sign.js [METHOD] [path?query]
// node scripts/oapi-sign.js --curl POST /oapi/print/submit # 输出可直接复制的 curl 命令
//
// 密钥来源(优先级):环境变量 APP_KEY / APP_SECRET → 文件默认值(开发联调密钥)
// 生产环境务必通过环境变量注入,勿提交真实密钥。
const crypto = require('crypto');
const APP_KEY = process.env.APP_KEY || '100002';
const APP_SECRET = process.env.APP_SECRET || '2314a3b158b24a838b2b9b69fd3db118';
// 排序 query(对齐 SignCanonical.SortRawQuery:k=v 整体排序,空值保留 = 号)
function sortQuery(raw) {
if (!raw) return '';
return raw.split('&').filter(Boolean).map(p => {
const i = p.indexOf('=');
return (i < 0 ? p : p.slice(0, i)) + '=' + (i < 0 ? '' : p.slice(i + 1));
}).sort().join('&');
}
function sign(method, pathWithQuery, ts) {
const qi = pathWithQuery.indexOf('?');
const target = qi >= 0
? pathWithQuery.slice(0, qi) + '?' + sortQuery(pathWithQuery.slice(qi + 1))
: pathWithQuery;
const source = method.toUpperCase() + '\n' + target + '\n' + ts;
const sig = crypto.createHmac('sha256', APP_SECRET).update(source, 'utf8').digest('base64');
return { ts, target, signature: sig };
}
const args = process.argv.slice(2);
let method = 'GET';
let pathWithQuery = '/oapi/hello';
let curlMode = false;
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (a === '--curl') { curlMode = true; continue; }
if (!/^-/.test(a)) {
if (method === 'GET' && !/^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)$/i.test(a) && !a.startsWith('/')) {
// 第一个非选项参数若不像 METHOD 也不像路径,则视为路径
pathWithQuery = a;
} else if (a.startsWith('/')) {
pathWithQuery = a;
} else {
method = a;
}
}
}
const { ts, target, signature } = sign(method, pathWithQuery, Date.now().toString());
if (curlMode) {
const u = target.replace(/^\//, '');
console.log(`curl -i -X ${method.toUpperCase()} "http://localhost:PORT/${u}" \\`);
console.log(` -H "X-App-Key: ${APP_KEY}" \\`);
console.log(` -H "X-Timestamp: ${ts}" \\`);
console.log(` -H "X-Signature: ${signature}"`);
} else {
console.log(JSON.stringify({ appKey: APP_KEY, method, target, ts, signature, curl: [
'-H', `X-App-Key: ${APP_KEY}`,
'-H', `X-Timestamp: ${ts}`,
'-H', `X-Signature: ${signature}`
].join(' ') }, null, 2));
}