ksyun-sdk-node 1.0.5 → 1.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +12 -0
- package/dist/base/BaseClient.js +133 -52
- package/dist/index.js +9 -12
- package/dist/lib/fetch.js +4 -5
- package/dist/lib/sign.js +31 -33
- package/dist/lib/signautreV4.js +167 -0
- package/dist/service/Actiontrail/v20190401/index.js +34 -37
- package/dist/service/Aicp/v20240612/index.js +511 -0
- package/dist/service/Bill/v20180601/index.js +49 -88
- package/dist/service/Bill/v20220601/index.js +64 -0
- package/dist/service/Bill_union/v20200101/index.js +151 -77
- package/dist/service/Bill_union/v20221222/index.js +142 -0
- package/dist/service/Bill_union/v20250801/index.js +66 -0
- package/dist/service/Bws/v20160304/index.js +111 -94
- package/dist/service/Cdn/v20160901/index.js +89 -0
- package/dist/service/Cdn/v20200630/index.js +410 -0
- package/dist/service/Cdn/v20200901/index.js +162 -0
- package/dist/service/Cdn/v20211201/index.js +45 -0
- package/dist/service/Cdn/v20250503/index.js +71 -0
- package/dist/service/Cen/v20160304/index.js +460 -0
- package/dist/service/Clickhouse/v20210101/index.js +546 -0
- package/dist/service/Ebs/v20160304/index.js +265 -268
- package/dist/service/Eip/v20160304/index.js +104 -107
- package/dist/service/Epc/v20151101/index.js +1735 -784
- package/dist/service/Iam/v20151101/index.js +872 -711
- package/dist/service/Iam/v20240513/index.js +47 -0
- package/dist/service/Iam/v20240703/index.js +44 -0
- package/dist/service/Kad/v20161122/index.js +84 -87
- package/dist/service/Kce/v20180314/index.js +320 -0
- package/dist/service/Kce/v20190806/index.js +482 -0
- package/dist/service/Kce/v20201231/index.js +63 -0
- package/dist/service/Kcf/v20211215/index.js +203 -0
- package/dist/service/Kcm/v20160304/index.js +120 -0
- package/dist/service/Kcrs/v20211109/index.js +851 -0
- package/dist/service/Kcs/v20160701/index.js +1106 -0
- package/dist/service/Kcs/v20170401/index.js +81 -0
- package/dist/service/Kead/v20200101/index.js +28 -31
- package/dist/service/Kec/v20160304/index.js +1695 -1466
- package/dist/service/Kes/v20201215/index.js +171 -0
- package/dist/service/Ket/v20170101/index.js +141 -0
- package/dist/service/Kkms/v20160304/index.js +167 -0
- package/dist/service/Klog/v20200731/index.js +331 -0
- package/dist/service/Kls/v20170101/index.js +194 -0
- package/dist/service/Kmr/v20210902/index.js +422 -0
- package/dist/service/Kmr/v20231231/index.js +154 -0
- package/dist/service/Kmr/v20240814/index.js +370 -0
- package/dist/service/Krds/v20160701/index.js +1302 -0
- package/dist/service/Krds/v20200825/index.js +174 -0
- package/dist/service/Memcached/v20180627/index.js +249 -0
- package/dist/service/Mongodb/v20170101/index.js +516 -501
- package/dist/service/Monitor/v20100525/index.js +70 -0
- package/dist/service/Monitor/v20181114/index.js +49 -0
- package/dist/service/Monitor/v20210101/index.js +216 -0
- package/dist/service/Monitor/v20220101/index.js +58 -0
- package/dist/service/Monitor/v20250101/index.js +71 -0
- package/dist/service/Rabbitmq/v20191017/index.js +242 -0
- package/dist/service/Resourcemanager/v20210320/index.js +113 -116
- package/dist/service/Sks/v20151101/index.js +72 -75
- package/dist/service/Slb/v20160304/index.js +1299 -790
- package/dist/service/Sts/v20151101/index.js +26 -29
- package/dist/service/Tagv2/v20200901/index.js +174 -0
- package/dist/service/Tidb/v20210520/index.js +363 -0
- package/dist/service/Trade/v20200114/index.js +23 -26
- package/dist/service/Trade/v20200831/index.js +25 -28
- package/dist/service/Vpc/v20160304/index.js +2015 -1045
- package/dist/service/Waf/v20200707/index.js +248 -0
- package/example/iam.js +2 -1
- package/example/res.js +2 -1
- package/package.json +1 -1
- package/src/base/BaseClient.js +131 -35
- package/src/lib/signautreV4.js +166 -0
- package/src/service/Actiontrail/v20190401/index.js +42 -42
- package/src/service/Aicp/v20240612/index.js +503 -0
- package/src/service/Bill/v20180601/index.js +61 -102
- package/src/service/Bill/v20220601/index.js +56 -0
- package/src/service/Bill_union/v20200101/index.js +181 -109
- package/src/service/Bill_union/v20221222/index.js +134 -0
- package/src/service/Bill_union/v20250801/index.js +58 -0
- package/src/service/Bws/v20160304/index.js +139 -119
- package/src/service/Cdn/v20160901/index.js +81 -0
- package/src/service/Cdn/v20200630/index.js +402 -0
- package/src/service/Cdn/v20200901/index.js +154 -0
- package/src/service/Cdn/v20211201/index.js +37 -0
- package/src/service/Cdn/v20250503/index.js +63 -0
- package/src/service/Cen/v20160304/index.js +452 -0
- package/src/service/Clickhouse/v20210101/index.js +538 -0
- package/src/service/Ebs/v20160304/index.js +365 -368
- package/src/service/Eip/v20160304/index.js +135 -136
- package/src/service/Epc/v20151101/index.js +1984 -1033
- package/src/service/Iam/v20151101/index.js +1155 -993
- package/src/service/Iam/v20240513/index.js +39 -0
- package/src/service/Iam/v20240703/index.js +36 -0
- package/src/service/Kad/v20161122/index.js +112 -112
- package/src/service/Kce/v20180314/index.js +312 -0
- package/src/service/Kce/v20190806/index.js +474 -0
- package/src/service/Kce/v20201231/index.js +55 -0
- package/src/service/Kcf/v20211215/index.js +195 -0
- package/src/service/Kcm/v20160304/index.js +112 -0
- package/src/service/Kcrs/v20211109/index.js +843 -0
- package/src/service/Kcs/v20160701/index.js +1098 -0
- package/src/service/Kcs/v20170401/index.js +73 -0
- package/src/service/Kead/v20200101/index.js +36 -36
- package/src/service/Kec/v20160304/index.js +2061 -1838
- package/src/service/Kes/v20201215/index.js +163 -0
- package/src/service/Ket/v20170101/index.js +133 -0
- package/src/service/Kkms/v20160304/index.js +159 -0
- package/src/service/Klog/v20200731/index.js +323 -0
- package/src/service/Kls/v20170101/index.js +186 -0
- package/src/service/Kmr/v20210902/index.js +414 -0
- package/src/service/Kmr/v20231231/index.js +146 -0
- package/src/service/Kmr/v20240814/index.js +362 -0
- package/src/service/Krds/v20160701/index.js +1294 -0
- package/src/service/Krds/v20200825/index.js +166 -0
- package/src/service/Memcached/v20180627/index.js +241 -0
- package/src/service/Mongodb/v20170101/index.js +672 -654
- package/src/service/Monitor/v20100525/index.js +62 -0
- package/src/service/Monitor/v20181114/index.js +41 -0
- package/src/service/Monitor/v20210101/index.js +208 -0
- package/src/service/Monitor/v20220101/index.js +50 -0
- package/src/service/Monitor/v20250101/index.js +63 -0
- package/src/service/Rabbitmq/v20191017/index.js +234 -0
- package/src/service/Resourcemanager/v20210320/index.js +157 -158
- package/src/service/Sks/v20151101/index.js +95 -96
- package/src/service/Slb/v20160304/index.js +1471 -959
- package/src/service/Sts/v20151101/index.js +34 -34
- package/src/service/Tagv2/v20200901/index.js +166 -0
- package/src/service/Tidb/v20210520/index.js +355 -0
- package/src/service/Trade/v20200114/index.js +31 -31
- package/src/service/Trade/v20200831/index.js +33 -33
- package/src/service/Vpc/v20160304/index.js +2404 -1432
- package/src/service/Waf/v20200707/index.js +240 -0
- package/src/service/Bill_union/v20211209/index.js +0 -35
- package/src/service/Slb/v20171210/index.js +0 -39
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
const BaseClient = require("../../../base/BaseClient.js");
|
|
7
|
+
module.exports = class Client extends BaseClient {
|
|
8
|
+
constructor(...args) {
|
|
9
|
+
super(...args);
|
|
10
|
+
_defineProperty(this, "_baseConfig", {
|
|
11
|
+
protocol: "http://",
|
|
12
|
+
endpoint: "waf.api.ksyun.com",
|
|
13
|
+
config: {
|
|
14
|
+
timeout: 60,
|
|
15
|
+
//设置timeout
|
|
16
|
+
headers: {
|
|
17
|
+
Accept: "application/json"
|
|
18
|
+
},
|
|
19
|
+
credentials: {
|
|
20
|
+
region: "cn-shanghai-3",
|
|
21
|
+
service: "waf"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
_defineProperty(this, "_apiList", {
|
|
26
|
+
CreateDomain: {
|
|
27
|
+
url: "/",
|
|
28
|
+
method: "GET",
|
|
29
|
+
config: {
|
|
30
|
+
query: {
|
|
31
|
+
Version: "2020-07-07",
|
|
32
|
+
Action: "CreateDomain"
|
|
33
|
+
},
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
paramsType: {
|
|
39
|
+
ResourceRecord: "String",
|
|
40
|
+
HttpRewrite: "Boolean",
|
|
41
|
+
HttpSource: "Boolean",
|
|
42
|
+
CertificateId: "String",
|
|
43
|
+
CertificateRegion: "String",
|
|
44
|
+
LbMethod: "String",
|
|
45
|
+
HasProxy: "Boolean",
|
|
46
|
+
ProjectId: "Int",
|
|
47
|
+
HeaderMark: "String",
|
|
48
|
+
HeaderValue: "String",
|
|
49
|
+
HealthMonitor: "String",
|
|
50
|
+
HttpPort: "Filter",
|
|
51
|
+
HttpsPort: "Filter",
|
|
52
|
+
Sources: "String"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
DescribeDomains: {
|
|
56
|
+
url: "/",
|
|
57
|
+
method: "GET",
|
|
58
|
+
config: {
|
|
59
|
+
query: {
|
|
60
|
+
Version: "2020-07-07",
|
|
61
|
+
Action: "DescribeDomains"
|
|
62
|
+
},
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
paramsType: {
|
|
68
|
+
ResourceRecord: "String"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
ModifyDomain: {
|
|
72
|
+
url: "/",
|
|
73
|
+
method: "GET",
|
|
74
|
+
config: {
|
|
75
|
+
query: {
|
|
76
|
+
Version: "2020-07-07",
|
|
77
|
+
Action: "ModifyDomain"
|
|
78
|
+
},
|
|
79
|
+
headers: {
|
|
80
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
paramsType: {
|
|
84
|
+
ResourceRecordId: "String",
|
|
85
|
+
HttpRewrite: "Boolean",
|
|
86
|
+
HttpSource: "Boolean",
|
|
87
|
+
CertificateId: "String",
|
|
88
|
+
CertificateRegion: "String",
|
|
89
|
+
LbMethod: "String",
|
|
90
|
+
HasProxy: "Boolean",
|
|
91
|
+
ProjectId: "Int",
|
|
92
|
+
HeaderMark: "String",
|
|
93
|
+
HeaderValue: "String",
|
|
94
|
+
HealthMonitor: "String",
|
|
95
|
+
HttpPort: "Filter",
|
|
96
|
+
HttpsPort: "Filter",
|
|
97
|
+
Sources: "String"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
DeleteDomain: {
|
|
101
|
+
url: "/",
|
|
102
|
+
method: "GET",
|
|
103
|
+
config: {
|
|
104
|
+
query: {
|
|
105
|
+
Version: "2020-07-07",
|
|
106
|
+
Action: "DeleteDomain"
|
|
107
|
+
},
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
paramsType: {
|
|
113
|
+
ResourceRecordId: "String"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
CreateAccessControlRule: {
|
|
117
|
+
url: "/",
|
|
118
|
+
method: "GET",
|
|
119
|
+
config: {
|
|
120
|
+
query: {
|
|
121
|
+
Version: "2020-07-07",
|
|
122
|
+
Action: "CreateAccessControlRule"
|
|
123
|
+
},
|
|
124
|
+
headers: {
|
|
125
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
paramsType: {
|
|
129
|
+
ResourceRecordId: "String",
|
|
130
|
+
RuleName: "String",
|
|
131
|
+
RuleType: "String",
|
|
132
|
+
ArgName: "String",
|
|
133
|
+
RuleData: "String",
|
|
134
|
+
MatchRule: "Int",
|
|
135
|
+
Level: "Int",
|
|
136
|
+
RuleAction: "Int",
|
|
137
|
+
Status: "Boolean"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
DescribeAccessControlRules: {
|
|
141
|
+
url: "/",
|
|
142
|
+
method: "GET",
|
|
143
|
+
config: {
|
|
144
|
+
query: {
|
|
145
|
+
Version: "2020-07-07",
|
|
146
|
+
Action: "DescribeAccessControlRules"
|
|
147
|
+
},
|
|
148
|
+
headers: {
|
|
149
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
paramsType: {
|
|
153
|
+
RuleId: "String",
|
|
154
|
+
ResourceRecordId: "String",
|
|
155
|
+
RuleName: "String"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
ModifyAccessControlRule: {
|
|
159
|
+
url: "/",
|
|
160
|
+
method: "GET",
|
|
161
|
+
config: {
|
|
162
|
+
query: {
|
|
163
|
+
Version: "2020-07-07",
|
|
164
|
+
Action: "ModifyAccessControlRule"
|
|
165
|
+
},
|
|
166
|
+
headers: {
|
|
167
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
paramsType: {
|
|
171
|
+
RuleId: "String",
|
|
172
|
+
RuleName: "String",
|
|
173
|
+
RuleType: "String",
|
|
174
|
+
RuleData: "String",
|
|
175
|
+
MatchRule: "String",
|
|
176
|
+
ArgName: "String",
|
|
177
|
+
Level: "Int",
|
|
178
|
+
RuleAction: "Int",
|
|
179
|
+
Status: "Boolean"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
DeleteAccessControlRule: {
|
|
183
|
+
url: "/",
|
|
184
|
+
method: "GET",
|
|
185
|
+
config: {
|
|
186
|
+
query: {
|
|
187
|
+
Version: "2020-07-07",
|
|
188
|
+
Action: "DeleteAccessControlRule"
|
|
189
|
+
},
|
|
190
|
+
headers: {
|
|
191
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
paramsType: {
|
|
195
|
+
RuleId: "String"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
DescribeCertificates: {
|
|
199
|
+
url: "/",
|
|
200
|
+
method: "GET",
|
|
201
|
+
config: {
|
|
202
|
+
query: {
|
|
203
|
+
Version: "2020-07-07",
|
|
204
|
+
Action: "DescribeCertificates"
|
|
205
|
+
},
|
|
206
|
+
headers: {
|
|
207
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
paramsType: {
|
|
211
|
+
Request: "String"
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
CreateIpv6Protection: {
|
|
215
|
+
url: "/",
|
|
216
|
+
method: "GET",
|
|
217
|
+
config: {
|
|
218
|
+
query: {
|
|
219
|
+
Version: "2020-07-07",
|
|
220
|
+
Action: "CreateIpv6Protection"
|
|
221
|
+
},
|
|
222
|
+
headers: {
|
|
223
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
paramsType: {
|
|
227
|
+
ResourceRecordId: "Array"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
DeleteIpv6Protection: {
|
|
231
|
+
url: "/",
|
|
232
|
+
method: "GET",
|
|
233
|
+
config: {
|
|
234
|
+
query: {
|
|
235
|
+
Version: "2020-07-07",
|
|
236
|
+
Action: "DeleteIpv6Protection"
|
|
237
|
+
},
|
|
238
|
+
headers: {
|
|
239
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
paramsType: {
|
|
243
|
+
ResourceRecordId: "Array"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
};
|
package/example/iam.js
CHANGED
|
@@ -14,7 +14,8 @@ const clientConfig = {
|
|
|
14
14
|
method: 'POST', // 请求方法 GET 或者 POST
|
|
15
15
|
timeout: 60, // 请求超时时间秒
|
|
16
16
|
protocol: '', // 协议 http:// 或者 https://
|
|
17
|
-
endpoint: '' // 接入点域名 如 iam.api.ksyun.com
|
|
17
|
+
endpoint: '', // 接入点域名 如 iam.api.ksyun.com
|
|
18
|
+
path: '' // 自定义URL路径 如 /api/v1/xxx
|
|
18
19
|
},
|
|
19
20
|
}
|
|
20
21
|
let client = new Client(clientConfig)
|
package/example/res.js
CHANGED
|
@@ -14,7 +14,8 @@ const clientConfig = {
|
|
|
14
14
|
method: '', // 请求方法 get 或者 post
|
|
15
15
|
timeout: 60, // 请求超时时间秒
|
|
16
16
|
protocol: 'http://', // 协议 http:// 或者 https://
|
|
17
|
-
endpoint: '' // 接入点域名 如 iam.api.ksyun.com
|
|
17
|
+
endpoint: '', // 接入点域名 如 iam.api.ksyun.com
|
|
18
|
+
path: '' // 自定义URL路径 如 /api/v1/xxx
|
|
18
19
|
},
|
|
19
20
|
}
|
|
20
21
|
let client = new Client(clientConfig)
|
package/package.json
CHANGED
package/src/base/BaseClient.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const {getSignatureHeaders, getCanonicalizedQuery} = require('../lib/signautreV4.js')
|
|
2
2
|
const fetch = require('../lib/fetch.js')
|
|
3
3
|
const dayjs = require('dayjs')
|
|
4
4
|
const utc = require('dayjs/plugin/utc.js')
|
|
@@ -26,67 +26,163 @@ module.exports = class BaseClient {
|
|
|
26
26
|
*/
|
|
27
27
|
request (apiAction, params = {}) {
|
|
28
28
|
|
|
29
|
+
params = this.formatParams(apiAction, params)
|
|
30
|
+
|
|
29
31
|
let apiConfig = this._apiList[apiAction]
|
|
30
|
-
let publicParams = {
|
|
31
|
-
Accesskey: this.ak,
|
|
32
|
-
Service: this._baseConfig.config.credentials.service,
|
|
33
|
-
Action: apiAction,
|
|
34
|
-
Version: apiConfig.config.query.Version,
|
|
35
|
-
Timestamp: dayjs().utc().format('YYYY-MM-DDThh:mm:ss')+'Z',
|
|
36
|
-
SignatureVersion: '1.0',
|
|
37
|
-
SignatureMethod: 'HMAC-SHA256',
|
|
38
|
-
Region: this.region || this._baseConfig.config.credentials.region,
|
|
39
|
-
}
|
|
40
32
|
|
|
41
|
-
let
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
let protocol = this.httpProfile.protocol || this._baseConfig.protocol
|
|
34
|
+
let endpoint = this.httpProfile.endpoint || this._baseConfig.endpoint
|
|
35
|
+
let method = (this.httpProfile.method || apiConfig.method).toUpperCase()
|
|
36
|
+
let region = this.region || this._baseConfig.config.credentials.region
|
|
37
|
+
let headers = {
|
|
38
|
+
...(this._baseConfig.config.headers || {}),
|
|
39
|
+
...(apiConfig.config.headers || {})
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
|
|
42
|
+
// 处理自定义path
|
|
43
|
+
let customPath = this.httpProfile.path || ''
|
|
44
|
+
// 清理path中的?参数
|
|
45
|
+
if (customPath && customPath.includes('?')) {
|
|
46
|
+
customPath = customPath.split('?')[0]
|
|
47
|
+
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
let
|
|
50
|
-
|
|
49
|
+
// 处理path拼接,避免双斜杠
|
|
50
|
+
let finalPath = apiConfig.url
|
|
51
|
+
if (customPath) {
|
|
52
|
+
// 清理endpoint末尾的斜杠
|
|
53
|
+
endpoint = endpoint.replace(/\/+$/, '')
|
|
54
|
+
// 确保customPath以/开头
|
|
55
|
+
if (!customPath.startsWith('/')) {
|
|
56
|
+
customPath = '/' + customPath
|
|
57
|
+
}
|
|
58
|
+
finalPath = customPath
|
|
59
|
+
}
|
|
51
60
|
|
|
52
|
-
let
|
|
53
|
-
if (['GET', '
|
|
54
|
-
|
|
61
|
+
let query = apiConfig.config.query
|
|
62
|
+
if (['GET', 'OPTION', 'HEAD'].includes(method)) {
|
|
63
|
+
query = {
|
|
64
|
+
...query,
|
|
65
|
+
...params
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
|
|
69
|
+
let body = this.getBody(method, headers['Content-Type'], params)
|
|
70
|
+
|
|
71
|
+
let signParams = {
|
|
72
|
+
path: finalPath,
|
|
73
|
+
query,
|
|
74
|
+
body: body || '',
|
|
75
|
+
headers,
|
|
76
|
+
host: endpoint,
|
|
77
|
+
method,
|
|
78
|
+
region,
|
|
79
|
+
service: this._baseConfig.config.credentials.service,
|
|
80
|
+
access_key: this.ak,
|
|
81
|
+
secret_key: this.sk,
|
|
61
82
|
}
|
|
62
|
-
|
|
83
|
+
|
|
84
|
+
let signHeaders = getSignatureHeaders(signParams)
|
|
85
|
+
|
|
86
|
+
let url = `${protocol}${endpoint}${finalPath}?${getCanonicalizedQuery(query)}`
|
|
63
87
|
|
|
64
88
|
let timeoutSecond = this.httpProfile.timeout || this._baseConfig.config.timeout
|
|
89
|
+
|
|
90
|
+
// 打印 curl 命令
|
|
91
|
+
this.printCurl(url, method, signHeaders, body)
|
|
92
|
+
|
|
65
93
|
return fetch(url, {
|
|
66
94
|
method: method,
|
|
67
95
|
timeout: timeoutSecond * 1000,
|
|
68
|
-
headers,
|
|
96
|
+
headers: signHeaders,
|
|
69
97
|
body
|
|
70
98
|
})
|
|
71
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* 格式化参数,对Filter类型做扁平处理
|
|
102
|
+
* @param {string} apiAction 接口名
|
|
103
|
+
* @param {object} params 参数值
|
|
104
|
+
* @returns 格式化后的参数
|
|
105
|
+
*/
|
|
106
|
+
formatParams (apiAction, params) {
|
|
107
|
+
let paramsType = this._apiList[apiAction].paramsType
|
|
108
|
+
if (!paramsType || params == null) {
|
|
109
|
+
return params
|
|
110
|
+
}
|
|
111
|
+
let res = {}
|
|
112
|
+
Object.keys(params).forEach(key => {
|
|
113
|
+
let type = paramsType[key]
|
|
114
|
+
// 这些类型不用处理,如果为null、undefined则排除掉
|
|
115
|
+
if (['String', 'Int', 'Double', 'Long', 'Boolean', 'Array'].includes(type) && params[key] != null) {
|
|
116
|
+
res[key] = params[key]
|
|
117
|
+
}
|
|
118
|
+
if (type == 'Filter' || type == 'Object') {
|
|
119
|
+
res = {
|
|
120
|
+
...res,
|
|
121
|
+
...this.formatFilter(key, params[key])
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
return res
|
|
126
|
+
}
|
|
127
|
+
formatFilter (pKey, value) {
|
|
128
|
+
let res = {}
|
|
129
|
+
Object.keys(value).forEach(key => {
|
|
130
|
+
let prefixName = `${pKey}.${key}`
|
|
131
|
+
let childValue = value[key]
|
|
132
|
+
if (typeof(childValue) == 'object') {
|
|
133
|
+
res = {
|
|
134
|
+
...res,
|
|
135
|
+
...this.formatFilter(prefixName, childValue)
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
res[prefixName] = childValue
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
return res
|
|
142
|
+
}
|
|
143
|
+
|
|
72
144
|
/**
|
|
73
145
|
* 获取body
|
|
74
146
|
* @param {string} method 请求类型
|
|
75
147
|
* @param {string} contentType
|
|
76
|
-
* @param {object}
|
|
148
|
+
* @param {object} params 参数对象
|
|
77
149
|
* @returns {string}
|
|
78
150
|
*/
|
|
79
|
-
getBody (method, contentType,
|
|
80
|
-
if (!['POST', 'PUT'].includes(method.
|
|
81
|
-
return
|
|
151
|
+
getBody (method, contentType, params) {
|
|
152
|
+
if (!['POST', 'PUT'].includes(method) || JSON.stringify(params) == '{}') {
|
|
153
|
+
return null
|
|
82
154
|
}
|
|
83
155
|
// 目前只有下面这两种
|
|
84
156
|
if (contentType == 'application/x-www-form-urlencoded') {
|
|
85
|
-
return qs.stringify(
|
|
157
|
+
return qs.stringify(params, {
|
|
158
|
+
allowDots: true, // 对象转成a.b.c
|
|
159
|
+
arrayFormat: 'indices' // 数组转成a[0]=b&a[1]=c
|
|
160
|
+
})
|
|
86
161
|
}
|
|
87
162
|
if (contentType == 'application/json') {
|
|
88
|
-
return JSON.stringify(
|
|
163
|
+
return JSON.stringify(params)
|
|
89
164
|
}
|
|
90
|
-
return JSON.stringify(
|
|
165
|
+
return JSON.stringify(params)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* 打印 curl 命令
|
|
170
|
+
*/
|
|
171
|
+
printCurl(url, method, headers, body) {
|
|
172
|
+
let curlCmd = `curl -X ${method} '${url}'`
|
|
173
|
+
|
|
174
|
+
// 添加 headers
|
|
175
|
+
Object.keys(headers).forEach(key => {
|
|
176
|
+
curlCmd += ` \\\n -H '${key}: ${headers[key]}'`
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
// 添加 body
|
|
180
|
+
if (body) {
|
|
181
|
+
curlCmd += ` \\\n -d '${body}'`
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
console.log('\n========== CURL 请求 ==========')
|
|
185
|
+
console.log(curlCmd)
|
|
186
|
+
console.log('================================\n')
|
|
91
187
|
}
|
|
92
188
|
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const crypto = require("crypto-js")
|
|
2
|
+
const dayjs = require('dayjs')
|
|
3
|
+
const utc = require('dayjs/plugin/utc.js')
|
|
4
|
+
|
|
5
|
+
dayjs.extend(utc)
|
|
6
|
+
|
|
7
|
+
const HEADERS_TO_IGNORE = {
|
|
8
|
+
'cache-control' : true,
|
|
9
|
+
'content-type' : true,
|
|
10
|
+
'content-length' : true,
|
|
11
|
+
'expect' : true,
|
|
12
|
+
'max-forwards' : true,
|
|
13
|
+
'pragma' : true,
|
|
14
|
+
'range' : true,
|
|
15
|
+
'te' : true,
|
|
16
|
+
'if-match' : true,
|
|
17
|
+
'if-none-match' : true,
|
|
18
|
+
'if-modified-since' : true,
|
|
19
|
+
'if-unmodified-since' : true,
|
|
20
|
+
'if-range' : true,
|
|
21
|
+
'accept' : true,
|
|
22
|
+
'authorization' : true,
|
|
23
|
+
'proxy-authorization' : true,
|
|
24
|
+
'from' : true,
|
|
25
|
+
'referer' : true,
|
|
26
|
+
'user-agent' : true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getSignatureKey(key, dateStamp, regionName, serviceName) {
|
|
30
|
+
var kDate = crypto.HmacSHA256(dateStamp, "AWS4" + key);
|
|
31
|
+
var kRegion = crypto.HmacSHA256(regionName, kDate);
|
|
32
|
+
var kService = crypto.HmacSHA256(serviceName, kRegion);
|
|
33
|
+
var kSigning = crypto.HmacSHA256("aws4_request", kService);
|
|
34
|
+
return kSigning;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 编码
|
|
39
|
+
* @param {*} str
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
function encodeRfc3986Full(str) {
|
|
43
|
+
// This function assumes the string has already been percent encoded
|
|
44
|
+
function encodeRfc3986(urlEncodedString) {
|
|
45
|
+
return urlEncodedString.replace(/[!'()*]/g, function (c) {
|
|
46
|
+
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
return encodeRfc3986(encodeURIComponent(str))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @param {*} path
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
function createCanonicalizedPath(path) {
|
|
58
|
+
return encodeRfc3986Full(path).replace(/%2F/g, '/')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getCanonicalHeaders(headers) {
|
|
62
|
+
function trimAll(header) {
|
|
63
|
+
return header.toString().trim().replace(/\s+/g, ' ')
|
|
64
|
+
}
|
|
65
|
+
return Object.keys(headers)
|
|
66
|
+
.filter(function (key) { return HEADERS_TO_IGNORE[key.toLowerCase()] == null })
|
|
67
|
+
.sort(function (a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 })
|
|
68
|
+
.map(function (key) { return key.toLowerCase() + ':' + trimAll(headers[key]) })
|
|
69
|
+
.join('\n') + '\n'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getSignedHeaders(headers) {
|
|
73
|
+
return Object.keys(headers)
|
|
74
|
+
.map(function (key) { return key.toLowerCase() })
|
|
75
|
+
.filter(function (key) { return HEADERS_TO_IGNORE[key] == null })
|
|
76
|
+
.sort()
|
|
77
|
+
.join(';')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
function getCanonicalizedQuery(query) {
|
|
82
|
+
if (!query) {
|
|
83
|
+
return ''
|
|
84
|
+
}
|
|
85
|
+
delete query['X-Amz-Signature'] // php项目里有这句
|
|
86
|
+
let res = [];
|
|
87
|
+
let sortKeys = Object.keys(query).sort()
|
|
88
|
+
sortKeys.forEach(key => {
|
|
89
|
+
if (!Array.isArray(query[key])) {
|
|
90
|
+
res.push(encodeRfc3986Full(key) + '=' + encodeRfc3986Full(query[key]))
|
|
91
|
+
} else {
|
|
92
|
+
query[key].map(encodeRfc3986Full).sort().forEach(val => {
|
|
93
|
+
res.push(encodeRfc3986Full(key) + '=' + encodeRfc3986Full(val))
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
return res.join('&')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 签名步骤摘要
|
|
101
|
+
// 要创建已签名的请求,请完成以下操作:
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 获取包含签名的头,含之前的头
|
|
105
|
+
* AWS Version 4
|
|
106
|
+
* https://docs.aws.amazon.com/zh_cn/general/latest/gr/sigv4_signing.html
|
|
107
|
+
* @param {string} path
|
|
108
|
+
* @param {string} query
|
|
109
|
+
*/
|
|
110
|
+
function getSignatureHeaders({
|
|
111
|
+
path, query, body, headers, host, method, region, service, secret_key, access_key
|
|
112
|
+
}) {
|
|
113
|
+
|
|
114
|
+
let now = dayjs().utc()
|
|
115
|
+
let amzdate = now.format(`YYYYMMDDTHHmmssZ`)
|
|
116
|
+
let datestamp = now.format('YYYYMMDD')
|
|
117
|
+
|
|
118
|
+
// 任务 1:针对签名版本 4 创建规范请求
|
|
119
|
+
// 将请求的内容(主体、操作、标头等)组织为标准(规范)格式。规范请求是用于创建待签字符串的输入之一。
|
|
120
|
+
|
|
121
|
+
let canonical_uri = createCanonicalizedPath(path)
|
|
122
|
+
let canonical_querystring = getCanonicalizedQuery(query)
|
|
123
|
+
|
|
124
|
+
let allHeaders = {
|
|
125
|
+
...headers,
|
|
126
|
+
host,
|
|
127
|
+
'x-amz-date': amzdate
|
|
128
|
+
}
|
|
129
|
+
let canonical_headers = getCanonicalHeaders(allHeaders)
|
|
130
|
+
let signed_headers = getSignedHeaders(allHeaders)
|
|
131
|
+
|
|
132
|
+
let payload_hash = headers['X-Amz-Content-Sha256'] || headers['x-amz-content-sha256'] ||
|
|
133
|
+
crypto.SHA256(body || '').toString()
|
|
134
|
+
|
|
135
|
+
let canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
// 任务 2:创建签名版本 4 的待签字符串
|
|
139
|
+
// 使用规范请求和额外信息(例如算法、请求日期、凭证范围和规范请求的摘要(哈希))创建待签字符串。
|
|
140
|
+
let algorithm = 'AWS4-HMAC-SHA256'
|
|
141
|
+
let credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
|
|
142
|
+
let string_to_sign = algorithm + '\n' + amzdate + '\n' + credential_scope + '\n' + crypto.SHA256(canonical_request).toString()
|
|
143
|
+
|
|
144
|
+
// 任务 3:为AWS签名版本 4 计算签名
|
|
145
|
+
// 使用AWS秘密访问密钥作为初始哈希操作的密钥,对请求日期、区域和服务执行一系列加密哈希操作(HMAC 操作),从而派生签名密钥。在派生签名密钥后,通过对待签字符串执行加密哈希操作来计算签名。使用派生的签名密钥作为此操作的哈希密钥。
|
|
146
|
+
let signing_key = getSignatureKey(secret_key, datestamp, region, service);
|
|
147
|
+
let signature = crypto.HmacSHA256(string_to_sign, signing_key).toString();
|
|
148
|
+
|
|
149
|
+
// 任务 4:将签名添加到 HTTP 请求
|
|
150
|
+
// 在计算签名后,将其添加到请求的 HTTP 标头或查询字符串中。
|
|
151
|
+
let authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
|
|
152
|
+
|
|
153
|
+
let res = {
|
|
154
|
+
...headers
|
|
155
|
+
}
|
|
156
|
+
res['x-amz-date'] = amzdate
|
|
157
|
+
res['Authorization'] = authorization_header
|
|
158
|
+
|
|
159
|
+
return res
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = {
|
|
164
|
+
getCanonicalizedQuery,
|
|
165
|
+
getSignatureHeaders
|
|
166
|
+
}
|