-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapiClient.js
More file actions
169 lines (144 loc) · 4.8 KB
/
apiClient.js
File metadata and controls
169 lines (144 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* 数电发票API
* 获取授权 客户端签名验证示例
* 请求接口: https://api.fa-piao.com/v5/enterprise/authorization
*/
const crypto = require('crypto');
const https = require('https');
const querystring = require('querystring');
const FormData = require('form-data');
// 配置信息
const config = {
baseUrl: 'https://api.fa-piao.com',
appKey: 'YOUR_APP_KEY', // 替换为您的AppKey
appSecret: 'YOUR_SECRET_KEY', // 替换为您的密钥
};
/**
* 生成随机字符串
* @param {number} length 字符串长度
* @returns {string} 随机字符串
*/
function generateRandomString(length = 16) {
const characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let randomString = '';
for (let i = 0; i < length; i++) {
randomString += characters.charAt(Math.floor(Math.random() * characters.length));
}
return randomString;
}
/**
* 计算签名
* @param {string} method HTTP方法
* @param {string} path 请求路径
* @param {string} randomString 随机字符串
* @param {string} timestamp 时间戳
* @param {string} appKey 应用密钥
* @param {string} appSecret 应用密钥
* @returns {string} 签名
*/
function calculateSignature(method, path, randomString, timestamp, appKey, appSecret) {
// 构建签名字符串,与服务器端保持一致
const signContent = `Method=${method}&Path=${path}&RandomString=${randomString}&TimeStamp=${timestamp}&AppKey=${appKey}`;
// 使用HMAC-SHA256计算签名,以secret作为密钥
const hmac = crypto.createHmac('sha256', appSecret);
hmac.update(signContent);
const signature = hmac.digest('hex');
// 转为大写
return signature.toUpperCase();
}
/**
* 发送请求
* @param {string} url 请求URL
* @param {object} formData 表单数据
* @param {object} headers 请求头
* @returns {Promise<object>} 响应结果
*/
function sendRequest(url, formData, headers) {
return new Promise((resolve, reject) => {
// 创建form-data
const form = new FormData();
for (const key in formData) {
form.append(key, formData[key]);
}
// 获取form-data的headers
const formHeaders = form.getHeaders();
// 解析URL
const urlObj = new URL(url);
// 请求选项
const options = {
hostname: urlObj.hostname,
port: urlObj.port || 443,
path: urlObj.pathname,
method: 'POST',
headers: {
...formHeaders,
...headers
},
rejectUnauthorized: false // 开发环境可设置为false,生产环境建议设置为true
};
// 删除Content-Type,使用form-data自动生成的
delete options.headers['Content-Type'];
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
http_code: res.statusCode,
response: data
});
});
});
req.on('error', (error) => {
console.error('请求错误:', error);
reject(error);
});
// 发送form-data
form.pipe(req);
});
}
/**
* 主函数
*/
async function main() {
try {
// 准备请求头参数
const method = 'POST';
const path = '/v5/enterprise/authorization';
// 请求参数
const formData = {
nsrsbh: '915101820724315989'
};
const randomString = generateRandomString(20);
const timestamp = Math.floor(Date.now() / 1000).toString(); // 当前时间戳
// 计算签名
const signature = calculateSignature(
method,
path,
randomString,
timestamp,
config.appKey,
config.appSecret
);
// 设置请求头
const headers = {
'AppKey': config.appKey,
'Sign': signature,
'TimeStamp': timestamp,
'RandomString': randomString
};
// 发送请求
const result = await sendRequest(config.baseUrl + path, formData, headers);
// 输出结果
console.log(`${method}: ${config.baseUrl}${path}`);
console.log(`headers: ${JSON.stringify(headers)}`);
console.log(`form-data: ${JSON.stringify(formData)}`);
console.log(`HTTP状态码: ${result.http_code}`);
console.log(`响应内容: ${result.response}`);
} catch (error) {
console.error(`发生错误: ${error.message}`);
}
}
// 执行主函数
main();