bjx-auth 1.0.0
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/dist/bjx-auth-api.es.js +2 -0
- package/dist/bjx-auth-api.umd.js +2 -0
- package/package.json +35 -0
- package/readme.md +69 -0
- package/src/config.js +59 -0
- package/src/logger.js +15 -0
- package/src/request/axios.js +67 -0
- package/src/request/index.js +12 -0
- package/src/request/passportapi.js +216 -0
- package/src/request/sign/encrypt/index.js +7 -0
- package/src/request/sign/encrypt/node.js +31 -0
- package/src/request/sign/encrypt/web.js +31 -0
- package/src/request/sign/hash/index.js +7 -0
- package/src/request/sign/hash/node.js +14 -0
- package/src/request/sign/hash/web.js +18 -0
- package/src/request/sign/index.js +59 -0
- package/src/request/sign/publicPem.js +45 -0
- package/src/request/sign/reqEncrypt.js +16 -0
- package/src/request/sign/reqSginOld.js +89 -0
- package/src/request/sign/reqSign.js +80 -0
- package/src/request/userInfo.js +72 -0
- package/src/strategy/handle.js +56 -0
- package/src/strategy/handleDemo.js +49 -0
- package/src/strategy/index.js +9 -0
- package/src/strategy/strategy.js +186 -0
- package/src/strategy/utils.js +265 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
const { passportapi } = require('./axios')
|
|
2
|
+
const { getReqBody } = require('./sign')
|
|
3
|
+
|
|
4
|
+
//https://passportapi.bjx.com.cn/swagger/swagger-ui/index.html#/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* nodejs授权
|
|
8
|
+
*/
|
|
9
|
+
async function token(opts, signObj = {}) {
|
|
10
|
+
opts.data = await getReqBody(null, false, signObj)
|
|
11
|
+
return passportapi({
|
|
12
|
+
url: '/api/v1/token/web',
|
|
13
|
+
method: 'POST',
|
|
14
|
+
...opts,
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function tokenRefresh(opts, signObj = {}) {
|
|
19
|
+
opts.data = await getReqBody(null, false, signObj)
|
|
20
|
+
return passportapi({
|
|
21
|
+
url: '/api/v1/token/refresh/web',
|
|
22
|
+
method: 'POST',
|
|
23
|
+
...opts,
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function getToken(opts, signObj) {
|
|
28
|
+
if (opts.__isRefresh__) {
|
|
29
|
+
return tokenRefresh(opts, signObj)
|
|
30
|
+
} else {
|
|
31
|
+
return token(opts, signObj)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 其他接口
|
|
37
|
+
*/
|
|
38
|
+
// 短信登录
|
|
39
|
+
async function loginSms(opts, signObj = {}) {
|
|
40
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
41
|
+
return passportapi({
|
|
42
|
+
url: '/api/v1/login/sms/web',
|
|
43
|
+
method: 'POST',
|
|
44
|
+
...opts,
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 密码登录
|
|
49
|
+
async function loginPwd(opts, signObj = {}) {
|
|
50
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
51
|
+
return passportapi({
|
|
52
|
+
url: '/api/v1/login/pwd/web',
|
|
53
|
+
method: 'POST',
|
|
54
|
+
...opts,
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 短信注册
|
|
59
|
+
async function registerSms(opts, signObj = {}) {
|
|
60
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
61
|
+
return passportapi({
|
|
62
|
+
url: '/api/v1/register/sms/web',
|
|
63
|
+
method: 'POST',
|
|
64
|
+
...opts,
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 账户登出 (set-cookie + 返回clear_cache回调地址)
|
|
69
|
+
async function logout(opts, signObj = {}) {
|
|
70
|
+
opts.data = await getReqBody(null, false, signObj)
|
|
71
|
+
return passportapi({
|
|
72
|
+
url: '/api/v1/logout/web',
|
|
73
|
+
method: 'POST',
|
|
74
|
+
...opts,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 快速登录/注册
|
|
79
|
+
async function loginSmsQuick(opts, signObj = {}) {
|
|
80
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
81
|
+
return passportapi({
|
|
82
|
+
url: '/api/v1/login/sms/quick/web',
|
|
83
|
+
method: 'POST',
|
|
84
|
+
...opts,
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 设置用户身份
|
|
89
|
+
async function userBusmold(opts, signObj = {}) {
|
|
90
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
91
|
+
return passportapi({
|
|
92
|
+
url: '/api/v1/user/busmold/seekers/set',
|
|
93
|
+
method: 'POST',
|
|
94
|
+
...opts,
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 根据手机号判断用户是否存在
|
|
99
|
+
async function userExist(opts, signObj = {}) {
|
|
100
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
101
|
+
return passportapi({
|
|
102
|
+
url: '/api/v1/user/exist/phone',
|
|
103
|
+
method: 'POST',
|
|
104
|
+
...opts,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 找回密码前验证码
|
|
109
|
+
async function pwdResetVerify(opts, signObj = {}) {
|
|
110
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
111
|
+
return passportapi({
|
|
112
|
+
url: '/api/v1/user/pwd/reset/verify',
|
|
113
|
+
method: 'POST',
|
|
114
|
+
...opts,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 找回密码
|
|
119
|
+
async function pwdReset(opts, signObj = {}) {
|
|
120
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
121
|
+
return passportapi({
|
|
122
|
+
url: '/api/v1/user/pwd/reset',
|
|
123
|
+
method: 'POST',
|
|
124
|
+
...opts,
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 获取公众号二维码
|
|
129
|
+
async function wxpubCode(opts, signObj = {}) {
|
|
130
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
131
|
+
return passportapi({
|
|
132
|
+
url: '/api/v1/wechat/wxpub/qrcode',
|
|
133
|
+
method: 'POST',
|
|
134
|
+
...opts,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 公众号扫码登录
|
|
139
|
+
async function wxpubScan(opts, signObj = {}) {
|
|
140
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
141
|
+
return passportapi({
|
|
142
|
+
url: '/api/v1/wechat/wxpub/scan/login',
|
|
143
|
+
method: 'POST',
|
|
144
|
+
...opts,
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 公众号登录后绑定
|
|
149
|
+
async function wxpubBindLogin(opts, signObj = {}) {
|
|
150
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
151
|
+
return passportapi({
|
|
152
|
+
url: '/api/v1/wechat/wxpub/scan/bindlogin',
|
|
153
|
+
method: 'POST',
|
|
154
|
+
...opts,
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function wxpubH5Code(opts, signObj = {}) {
|
|
159
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
160
|
+
return passportapi({
|
|
161
|
+
url: '/api/v1/wechat/wxpub/h5/getcode',
|
|
162
|
+
method: 'POST',
|
|
163
|
+
...opts,
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function wxpubH5BindLogin(opts, signObj = {}) {
|
|
168
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
169
|
+
return passportapi({
|
|
170
|
+
url: '/api/v1/wechat/wxpub/h5/bindlogin',
|
|
171
|
+
method: 'POST',
|
|
172
|
+
...opts,
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function webappCode(opts, signObj = {}) {
|
|
177
|
+
opts.data = await getReqBody(opts.data, false, signObj)
|
|
178
|
+
return passportapi({
|
|
179
|
+
url: '/api/v1/wechat/webapp/code',
|
|
180
|
+
method: 'POST',
|
|
181
|
+
...opts,
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function webappBindLogin(opts, signObj = {}) {
|
|
186
|
+
opts.data = await getReqBody(opts.data, true, signObj)
|
|
187
|
+
return passportapi({
|
|
188
|
+
url: '/api/v1/wechat/webapp/bindlogin',
|
|
189
|
+
method: 'POST',
|
|
190
|
+
...opts,
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
exports = module.exports = {
|
|
195
|
+
getToken,
|
|
196
|
+
loginSms,
|
|
197
|
+
loginPwd,
|
|
198
|
+
registerSms,
|
|
199
|
+
logout,
|
|
200
|
+
|
|
201
|
+
loginSmsQuick,
|
|
202
|
+
userBusmold,
|
|
203
|
+
userExist,
|
|
204
|
+
pwdResetVerify,
|
|
205
|
+
pwdReset,
|
|
206
|
+
|
|
207
|
+
wxpubCode,
|
|
208
|
+
wxpubScan,
|
|
209
|
+
wxpubBindLogin,
|
|
210
|
+
|
|
211
|
+
wxpubH5Code,
|
|
212
|
+
wxpubH5BindLogin,
|
|
213
|
+
|
|
214
|
+
webappCode,
|
|
215
|
+
webappBindLogin,
|
|
216
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const crypto = require('crypto')
|
|
2
|
+
|
|
3
|
+
function encryptRSA(str, publicPem) {
|
|
4
|
+
if (!publicPem) throw new Error('publicPem is required')
|
|
5
|
+
const dataBuffer = Buffer.from(str, 'utf8')
|
|
6
|
+
const encrypted = crypto.publicEncrypt(
|
|
7
|
+
{
|
|
8
|
+
key: publicPem,
|
|
9
|
+
padding: crypto.constants.RSA_PKCS1_PADDING,
|
|
10
|
+
},
|
|
11
|
+
dataBuffer,
|
|
12
|
+
)
|
|
13
|
+
return encrypted.toString('base64')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function encryptAES(str) {
|
|
17
|
+
const iv = crypto.randomBytes(16) // 密匙和IV一致
|
|
18
|
+
const key = iv
|
|
19
|
+
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv)
|
|
20
|
+
let encrypted = cipher.update(str, 'utf8', 'base64')
|
|
21
|
+
encrypted += cipher.final('base64')
|
|
22
|
+
return {
|
|
23
|
+
iv: iv.toString('hex'),
|
|
24
|
+
encrypted,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports = module.exports = {
|
|
29
|
+
encryptRSA,
|
|
30
|
+
encryptAES,
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const JSEncrypt = require('jsencrypt')
|
|
2
|
+
|
|
3
|
+
const AES = require('crypto-js/aes')
|
|
4
|
+
const WordArray = require('crypto-js/lib-typedarrays')
|
|
5
|
+
const Pkcs7 = require('crypto-js/pad-pkcs7')
|
|
6
|
+
const Hex = require('crypto-js/enc-hex')
|
|
7
|
+
|
|
8
|
+
function encryptRSA(str, publicPem) {
|
|
9
|
+
if (!publicPem) throw new Error('publicPem is required')
|
|
10
|
+
const encryptor = new JSEncrypt()
|
|
11
|
+
encryptor.setPublicKey(publicPem)
|
|
12
|
+
const encrypted = encryptor.encrypt(str)
|
|
13
|
+
return encrypted
|
|
14
|
+
}
|
|
15
|
+
function encryptAES(str) {
|
|
16
|
+
const iv = WordArray.random(16) // 密匙和IV一致
|
|
17
|
+
const key = iv
|
|
18
|
+
const encrypted = AES.encrypt(str, key, {
|
|
19
|
+
iv,
|
|
20
|
+
padding: Pkcs7,
|
|
21
|
+
})
|
|
22
|
+
return {
|
|
23
|
+
iv: iv.toString(Hex),
|
|
24
|
+
encrypted: encrypted.toString(),
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports = module.exports = {
|
|
29
|
+
encryptRSA,
|
|
30
|
+
encryptAES,
|
|
31
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const crypto = require('crypto')
|
|
2
|
+
|
|
3
|
+
function hashHS256(str, key) {
|
|
4
|
+
return crypto.createHmac('sha256', key).update(str).digest('base64')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function hashMD5(str) {
|
|
8
|
+
return crypto.createHash('md5').update(str).digest('hex').toUpperCase()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports = module.exports = {
|
|
12
|
+
hashHS256,
|
|
13
|
+
hashMD5,
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const HmacSHA256 = require('crypto-js/hmac-sha256')
|
|
2
|
+
const Base64 = require('crypto-js/enc-base64')
|
|
3
|
+
|
|
4
|
+
const MD5 = require('crypto-js/md5')
|
|
5
|
+
const Hex = require('crypto-js/enc-hex')
|
|
6
|
+
|
|
7
|
+
function hashHS256(str, key) {
|
|
8
|
+
return HmacSHA256(str, key).toString(Base64)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function hashMD5(str) {
|
|
12
|
+
return MD5(str).toString(Hex)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports = module.exports = {
|
|
16
|
+
hashHS256,
|
|
17
|
+
hashMD5,
|
|
18
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const reqSign = require('./reqSign')
|
|
2
|
+
const reqEncrypt = require('./reqEncrypt')
|
|
3
|
+
const reqSginOld = require('./reqSginOld')
|
|
4
|
+
|
|
5
|
+
async function getReqBody(data, isEncrypt, opts) {
|
|
6
|
+
let {
|
|
7
|
+
eqp = '',
|
|
8
|
+
os = '',
|
|
9
|
+
ba = '',
|
|
10
|
+
bp = '',
|
|
11
|
+
ver = '',
|
|
12
|
+
apiVersion = '',
|
|
13
|
+
signVersion = '',
|
|
14
|
+
clientId = '',
|
|
15
|
+
clientSecret = '',
|
|
16
|
+
ctx,
|
|
17
|
+
} = opts || {}
|
|
18
|
+
if (ctx) {
|
|
19
|
+
if (!eqp) {
|
|
20
|
+
eqp = ctx.uuid
|
|
21
|
+
}
|
|
22
|
+
if (!os) {
|
|
23
|
+
eqp = ctx.isMobi ? 2 : 1
|
|
24
|
+
}
|
|
25
|
+
if (!ba) {
|
|
26
|
+
ba = ctx.query.ba
|
|
27
|
+
}
|
|
28
|
+
if (!bp) {
|
|
29
|
+
bp = ctx.query.bp
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const obj = {
|
|
34
|
+
eqp,
|
|
35
|
+
os,
|
|
36
|
+
ba,
|
|
37
|
+
bp,
|
|
38
|
+
ver,
|
|
39
|
+
apiVersion,
|
|
40
|
+
signVersion,
|
|
41
|
+
clientId,
|
|
42
|
+
clientSecret,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (isEncrypt && data && Object.keys(data).length > 0) {
|
|
46
|
+
obj.data = await reqEncrypt(data)
|
|
47
|
+
} else {
|
|
48
|
+
obj.data = data || {}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return reqSign(obj)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports = module.exports = {
|
|
55
|
+
reqSign,
|
|
56
|
+
reqEncrypt,
|
|
57
|
+
getReqBody,
|
|
58
|
+
...reqSginOld,
|
|
59
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const reqSign = require('./reqSign')
|
|
2
|
+
const { passportapi } = require('../axios')
|
|
3
|
+
const { errorLogger } = require('../../logger')
|
|
4
|
+
|
|
5
|
+
// 获取公钥
|
|
6
|
+
let publicPemCache = null
|
|
7
|
+
async function getPublicPem() {
|
|
8
|
+
if (publicPemCache && publicPemCache.expiresAt > Date.now()) {
|
|
9
|
+
return publicPemCache.value
|
|
10
|
+
}
|
|
11
|
+
let body = reqSign()
|
|
12
|
+
try {
|
|
13
|
+
const { data } = await passportapi({
|
|
14
|
+
url: '/api/v1/common/config/security',
|
|
15
|
+
method: 'POST',
|
|
16
|
+
data: body,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
if (data.isError === false) {
|
|
20
|
+
publicPemCache = {
|
|
21
|
+
value: `-----BEGIN PUBLIC KEY-----\n${data.data.rsaPubkey}\n-----END PUBLIC KEY-----`,
|
|
22
|
+
expiresAt: Date.now() + 8 * 3600 * 1000,
|
|
23
|
+
}
|
|
24
|
+
return publicPemCache.value
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(data.error)
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
errorLogger(error)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function clearPublicPemCache() {
|
|
34
|
+
publicPemCache = null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hasPublicPemCache() {
|
|
38
|
+
return !!publicPemCache
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports = module.exports = {
|
|
42
|
+
getPublicPem,
|
|
43
|
+
clearPublicPemCache,
|
|
44
|
+
hasPublicPemCache,
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { getPublicPem } = require('./publicPem')
|
|
2
|
+
const { encryptRSA, encryptAES } = require('./encrypt')
|
|
3
|
+
|
|
4
|
+
async function getReqEncrypt(data) {
|
|
5
|
+
if (!data) throw new Error('data is required')
|
|
6
|
+
const publicPem = await getPublicPem()
|
|
7
|
+
const dataStr = JSON.stringify(data)
|
|
8
|
+
const { encrypted, iv } = encryptAES(dataStr)
|
|
9
|
+
const encryptedIv = encryptRSA(iv, publicPem)
|
|
10
|
+
return {
|
|
11
|
+
akaParams: encrypted,
|
|
12
|
+
secretKey: encryptedIv,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports = module.exports = getReqEncrypt
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const { hashMD5 } = require('./hash')
|
|
2
|
+
const config = require('../../config')
|
|
3
|
+
|
|
4
|
+
function getReqSign(params, ...moreParams) {
|
|
5
|
+
if (typeof params === 'string') {
|
|
6
|
+
params = {
|
|
7
|
+
EQP: params || '',
|
|
8
|
+
OS: moreParams[0] || '',
|
|
9
|
+
BA: moreParams[1] || '',
|
|
10
|
+
BP: moreParams[2] || '',
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
let { EQP, OS, BA, BP, Ver, ctx } = params || {}
|
|
14
|
+
if (ctx) {
|
|
15
|
+
if (!EQP) {
|
|
16
|
+
EQP = ctx.uuid
|
|
17
|
+
}
|
|
18
|
+
if (!OS) {
|
|
19
|
+
OS = ctx.isMobi ? 2 : 1
|
|
20
|
+
}
|
|
21
|
+
if (!BA) {
|
|
22
|
+
BA = ctx.query.ba
|
|
23
|
+
}
|
|
24
|
+
if (!BP) {
|
|
25
|
+
BP = ctx.query.bp
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const obj = {
|
|
30
|
+
EQP: EQP || config.eqp || '',
|
|
31
|
+
OS: OS || config.os * 1 || 1,
|
|
32
|
+
BA: BA || config.ba || '',
|
|
33
|
+
BP: BP || config.bp || '',
|
|
34
|
+
Ver: Ver || config.ver || '1.0.0',
|
|
35
|
+
TS: Date.now(),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const secret = 'bjxstat2019'
|
|
39
|
+
const signStr = `EQP=${obj.EQP}&OS=${obj.OS}&BA=${obj.BA}&BP=${obj.BP}&Ver=${obj.Ver}&TS=${obj.TS}+${secret}`
|
|
40
|
+
const Sign = hashMD5(signStr).toUpperCase()
|
|
41
|
+
return Object.assign(obj, { Sign })
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getReqSign2(params, ...moreParams) {
|
|
45
|
+
if (typeof params === 'string') {
|
|
46
|
+
params = {
|
|
47
|
+
EQP: params || '',
|
|
48
|
+
OS: moreParams[0] || '',
|
|
49
|
+
BA: moreParams[1] || '',
|
|
50
|
+
BP: moreParams[2] || '',
|
|
51
|
+
XAppId: moreParams[3] || '',
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let { EQP, OS, BA, BP, Ver, XAppId, ctx } = params || {}
|
|
55
|
+
if (ctx) {
|
|
56
|
+
if (!EQP) {
|
|
57
|
+
EQP = ctx.uuid
|
|
58
|
+
}
|
|
59
|
+
if (!OS) {
|
|
60
|
+
OS = ctx.isMobi ? 2 : 1
|
|
61
|
+
}
|
|
62
|
+
if (!BA) {
|
|
63
|
+
BA = ctx.query.ba
|
|
64
|
+
}
|
|
65
|
+
if (!BP) {
|
|
66
|
+
BP = ctx.query.bp
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const obj = {
|
|
71
|
+
EQP: EQP || config.eqp || '',
|
|
72
|
+
OS: OS || config.os * 1 || 1,
|
|
73
|
+
BA: BA || config.ba || '',
|
|
74
|
+
BP: BP || config.bp || '',
|
|
75
|
+
Ver: Ver || config.ver || '1.0.0',
|
|
76
|
+
TS: Date.now(),
|
|
77
|
+
XAppId: XAppId || config.clientId || '',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const secret = '%SiGn2021!@#'
|
|
81
|
+
const signStr = `EQP=${obj.EQP}&OS=${obj.OS}&BA=${obj.BA}&BP=${obj.BP}&Ver=${obj.Ver}&TS=${obj.TS}&XAppId=${obj.XAppId}+${secret}`
|
|
82
|
+
const Sign = hashMD5(signStr).toUpperCase()
|
|
83
|
+
return Object.assign(obj, { Sign })
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
exports = module.exports = {
|
|
87
|
+
getReqSign,
|
|
88
|
+
getReqSign2,
|
|
89
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const { hashHS256 } = require('./hash')
|
|
2
|
+
const config = require('../../config')
|
|
3
|
+
|
|
4
|
+
// 请求签名相关
|
|
5
|
+
function sortData(data) {
|
|
6
|
+
if (Object.prototype.toString.call(data) === '[object Object]') {
|
|
7
|
+
return Object.keys(data)
|
|
8
|
+
.sort() // 默认情况下 sort 会按字典顺序(ASCII 顺序)进行排序
|
|
9
|
+
.reduce((newObj, key) => {
|
|
10
|
+
newObj[key] = sortData(data[key])
|
|
11
|
+
return newObj
|
|
12
|
+
}, {})
|
|
13
|
+
} else if (Object.prototype.toString.call(data) === '[object Array]') {
|
|
14
|
+
return data.map((item) => sortData(item))
|
|
15
|
+
} else {
|
|
16
|
+
return data
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function objToStr(data) {
|
|
20
|
+
let dataArr = []
|
|
21
|
+
Object.entries(data).map(([key, value]) => {
|
|
22
|
+
if (value === undefined || value === '' || value === null) {
|
|
23
|
+
} else {
|
|
24
|
+
if (
|
|
25
|
+
Object.prototype.toString.call(value) === '[object Array]' ||
|
|
26
|
+
Object.prototype.toString.call(value) === '[object Object]'
|
|
27
|
+
) {
|
|
28
|
+
dataArr.push(`${key}=${encodeURIComponent(JSON.stringify(value))}`)
|
|
29
|
+
} else {
|
|
30
|
+
dataArr.push(`${key}=${encodeURIComponent(value)}`)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
return dataArr.join('&')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function signFn(data, signKey) {
|
|
38
|
+
const sorted = sortData(data)
|
|
39
|
+
const dataStr = objToStr(sorted)
|
|
40
|
+
const sign = hashHS256(dataStr, signKey)
|
|
41
|
+
return {
|
|
42
|
+
...data,
|
|
43
|
+
sign,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getReqSign(params, signKey) {
|
|
48
|
+
const {
|
|
49
|
+
eqp,
|
|
50
|
+
os,
|
|
51
|
+
ba,
|
|
52
|
+
bp,
|
|
53
|
+
ver,
|
|
54
|
+
apiVersion,
|
|
55
|
+
signVersion,
|
|
56
|
+
clientId,
|
|
57
|
+
clientSecret,
|
|
58
|
+
data = {},
|
|
59
|
+
} = params || {}
|
|
60
|
+
|
|
61
|
+
const obj = {
|
|
62
|
+
eqp: eqp || config.eqp || '',
|
|
63
|
+
os: os * 1 || config.os * 1 || 1,
|
|
64
|
+
ba: ba || config.ba || '',
|
|
65
|
+
bp: bp || config.bp || '',
|
|
66
|
+
ver: ver || config.ver || '1.0.0',
|
|
67
|
+
ts: Date.now(),
|
|
68
|
+
apiVersion: apiVersion || config.apiVersion || '1.0.0',
|
|
69
|
+
signVersion: signVersion || config.signVersion || 'V1',
|
|
70
|
+
clientId: clientId || config.clientId || '',
|
|
71
|
+
clientSecret: clientSecret || config.clientSecret || '',
|
|
72
|
+
data,
|
|
73
|
+
}
|
|
74
|
+
signKey = signKey || config.signKey
|
|
75
|
+
|
|
76
|
+
const res = signFn(obj, signKey)
|
|
77
|
+
return res
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exports = module.exports = getReqSign
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const { auth, enterpriseapi } = require('./axios')
|
|
2
|
+
const { getReqSign } = require('./sign')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* nodejs授权
|
|
6
|
+
*/
|
|
7
|
+
async function baseInfo(opts, signObj = {}) {
|
|
8
|
+
opts.data = { ...opts.data, ...getReqSign(signObj) }
|
|
9
|
+
return auth({
|
|
10
|
+
url: '/api/User/' + opts.__type__,
|
|
11
|
+
method: 'POST',
|
|
12
|
+
...opts,
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function userInfo(opts, signObj = {}) {
|
|
17
|
+
opts.data = { ...opts.data, ...getReqSign(signObj) }
|
|
18
|
+
return enterpriseapi({
|
|
19
|
+
url: '/enterprise/user/userInfo',
|
|
20
|
+
method: 'POST',
|
|
21
|
+
...opts,
|
|
22
|
+
}).then((res) => {
|
|
23
|
+
const { data: rsp_obj } = res
|
|
24
|
+
res.data = {
|
|
25
|
+
HttpStatusCode: rsp_obj.code,
|
|
26
|
+
Error: rsp_obj.errMsg,
|
|
27
|
+
IsError: !rsp_obj.success,
|
|
28
|
+
Data:
|
|
29
|
+
rsp_obj.data && Object.keys(rsp_obj.data).length
|
|
30
|
+
? {
|
|
31
|
+
HasCompany: rsp_obj.data.hasCompanyState > 0, // BaseInfoV1和BaseInfo的差别
|
|
32
|
+
Id: rsp_obj.data.id || '',
|
|
33
|
+
UId: rsp_obj.data.userId || 0,
|
|
34
|
+
UserName: rsp_obj.data.userName || '',
|
|
35
|
+
NickName: rsp_obj.data.nickName || '',
|
|
36
|
+
Email: rsp_obj.data.userEmail || '',
|
|
37
|
+
EmailIsCheck: rsp_obj.data.emailCheckState > 0,
|
|
38
|
+
RegionCode: rsp_obj.data.regionCode || '',
|
|
39
|
+
Phone: rsp_obj.data.userPhone || '',
|
|
40
|
+
PhoneIsCheck: rsp_obj.data.phoneCheckState > 0,
|
|
41
|
+
HeadUrl: rsp_obj.data.headUrl || '',
|
|
42
|
+
BackImage: rsp_obj.data.backImage || '',
|
|
43
|
+
BriefIntro: rsp_obj.data.briefIntro || '',
|
|
44
|
+
Industry: rsp_obj.data.industryId || 0,
|
|
45
|
+
Source: rsp_obj.data.registerSource || 0,
|
|
46
|
+
ShowName: rsp_obj.data.showName || '',
|
|
47
|
+
HeadIsDef: rsp_obj.data.headDefState > 0,
|
|
48
|
+
Nick: rsp_obj.data.nick || '',
|
|
49
|
+
NickShowName: rsp_obj.data.nickShowName || '',
|
|
50
|
+
RegDate: rsp_obj.data.registerDate || '',
|
|
51
|
+
}
|
|
52
|
+
: {},
|
|
53
|
+
}
|
|
54
|
+
return res
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function getUserInfo(opts, signArr) {
|
|
59
|
+
const typeArr = ['BaseInfo', 'BaseInfoV1', 'ExtendInfo', 'userInfo']
|
|
60
|
+
if (!typeArr.includes(opts.__type__)) {
|
|
61
|
+
opts.__type__ = typeArr[0]
|
|
62
|
+
}
|
|
63
|
+
if (opts.__type__ === 'userInfo') {
|
|
64
|
+
return userInfo(opts, signArr)
|
|
65
|
+
} else {
|
|
66
|
+
return baseInfo(opts, signArr)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports = module.exports = {
|
|
71
|
+
getUserInfo,
|
|
72
|
+
}
|