# API签名工具 - TypeScript实现 ## 项目结构 根据实际项目文件结构: ```plaintext typescript/ ├── src/ │ ├── index.ts # 主模块和核心实现 │ └── cli.ts # 命令行工具入口 ├── dist/ # 编译输出目录 ├── node_modules/ # 依赖包目录 ├── package.json # 项目配置 ├── package-lock.json # 依赖锁定文件 └── tsconfig.json # TypeScript配置 ``` ## 使用方法 ### 安装依赖 ```bash npm install ``` ### 构建项目 ```bash npm run build ``` ### 运行命令行工具 ```bash npm start -- [选项] ``` 或直接运行编译后的CLI: ```bash node dist/cli.js [选项] ``` ### 命令行选项 | 选项 | 描述 | |------|------| | `-a, --algorithm` | 签名算法: md5, sha1, sha256, hmac-sha256 | | `-u, --url` | API基础URL | | `-p, --param` | 请求参数,格式为key=value,可多次使用 | | `-k, --key` | 访问密钥ID | | `-s, --secret` | 密钥 | | `-c, --channel` | 合作渠道方ID | | `-h, --help` | 显示帮助信息 | | `-m, --mode` | 操作模式: url, params, verify | | `-j, --json` | 以JSON格式指定参数 | | `-v, --version` | 显示版本信息 | ### 常用命令示例 **基本用法** ```bash node dist/cli.js ``` **自定义参数** ```bash node dist/cli.js \ -u "https://api.example.com/user/info" \ -p "userId=12345" -p "action=getInfo" \ -k "YOUR_ACCESS_KEY" \ -s "YOUR_SECRET_KEY" \ -c "3" ``` **使用JSON参数** ```bash node dist/cli.js -j '{"userId": "12345", "action": "getData"}' ``` **指定签名算法** ```bash node dist/cli.js -a sha256 ``` **生成签名参数** ```bash node dist/cli.js -m params -p "userId=12345" -p "action=getData" ``` **验证签名** ```bash node dist/cli.js -m verify -p "userId=12345" -p "action=getData" -p "AccessKeyId=test-key" -p "channelId=test-channel" -p "timestamp=1621234567890" -p "nonce=abc123" -p "sign=calculated-signature-here" ``` **帮助信息** ```bash node dist/cli.js --help ``` ### API接口测试实例 使用真实API接口进行测试: ```bash # 未签名的API调用测试 - 返回错误 curl "https://api-v1.sound-force.com:8443/p/album/single/media-url?channelId=3&singleId=381980" # 返回: {"code":400,"data":null,"msg":"Missing AccessKeyId","success":false} # 生成访问https://api-v1.sound-force.com:8443/p/album/single/media-url的签名URL node dist/cli.js \ -a md5 \ -u "https://api-v1.sound-force.com:8443/p/album/single/media-url" \ -p "singleId=381980" \ -k "YOUR_ACCESS_KEY" \ -s "YOUR_SECRET_KEY" \ -c "3" # 使用curl测试API接口 signed_url=$(node dist/cli.js \ -a md5 \ -u "https://api-v1.sound-force.com:8443/p/album/single/media-url" \ -p "singleId=381980" \ -k "YOUR_ACCESS_KEY" \ -s "YOUR_SECRET_KEY" \ -c "3" | grep -A 1 "签名后的URL:" | tail -n 1) curl -v "$signed_url" ``` 请注意: - 替换`YOUR_ACCESS_KEY`为实际的访问密钥ID - 替换`YOUR_SECRET_KEY`为实际的密钥 - 示例使用的渠道ID为`3`,请根据实际情况调整 使用有效的密钥和签名后,API接口将返回成功响应(状态码200)并提供媒体URL数据。 ### Node.js HTTP客户端测试示例 ```javascript const { execSync } = require('child_process'); const https = require('https'); const url = require('url'); // 获取签名URL const output = execSync('node dist/cli.js -a md5 -u "https://api-v1.sound-force.com:8443/p/album/single/media-url" -p "singleId=381980" -k "YOUR_ACCESS_KEY" -s "YOUR_SECRET_KEY" -c "3"').toString(); const lines = output.split('\n'); let signedUrl = ''; for (let i = 0; i < lines.length; i++) { if (lines[i].includes('签名后的URL:') && i + 1 < lines.length) { signedUrl = lines[i + 1].trim(); break; } } console.log('签名生成的URL:', signedUrl); if (signedUrl) { // 解析URL const parsedUrl = url.parse(signedUrl); // 创建请求选项 const options = { hostname: parsedUrl.hostname, port: parsedUrl.port, path: parsedUrl.path, method: 'GET', rejectUnauthorized: false // 忽略SSL证书验证,仅用于测试 }; // 发送请求 const req = https.request(options, (res) => { console.log(`状态码: ${res.statusCode}`); let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log(`响应内容: ${data}`); }); }); req.on('error', (error) => { console.error(`请求错误: ${error.message}`); }); req.end(); } else { console.error('无法从输出中获取签名URL'); } ``` ### 代码集成 ```typescript import { ApiSigner, SignOptions, SignatureAlgorithm } from './dist'; // 创建签名选项 const options: SignOptions = { algorithm: SignatureAlgorithm.MD5 }; // 创建签名工具 const signer = new ApiSigner(options); // 准备请求参数 const params = { singleId: '381980' }; // 执行签名 const signedParams = signer.signRequest( params, 'YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY', '3' ); // 或签名URL const signedUrl = signer.signUrl( 'https://api-v1.sound-force.com:8443/p/album/single/media-url', params, 'YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY', '3' ); console.log(signedUrl); ``` ### 浏览器使用 ```html ``` ### 环境变量 该工具支持从`.env`文件加载以下配置: - `ACCESS_KEY_ID`: 访问密钥ID - `SECRET_KEY`: 密钥 - `CHANNEL_ID`: 渠道ID - `SIGN_ALGORITHM`: 签名算法 - `API_BASE_URL`: API基础URL