forked from maimai-tech/wx-check-domain
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
153 lines (144 loc) · 5.08 KB
/
index.js
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
'use strict';
const Storage = require('node-storage');
const request = require('request');
const querystring = require('querystring');
/**
* @param {String} appid 在公众平台上申请得到的appid
* @param {String} appsecret 在公众平台上申请得到的app secret
* @param {String} path 存储access_token的路径,默认store/access_token
*/
class Checker {
constructor(appid, appsecret, path) {
this.appid = appid;
this.appsecret = appsecret;
this.store = new Storage('store/access_token');
this.expires_in = 7200;
}
/**
* 根据appid和app appsecret来获取acess_token
* return @param {String}
*/
async getAccessToken() {
let query = {
appid: this.appid,
secret: this.appsecret,
grant_type: 'client_credential'
};
let url = `https://api.weixin.qq.com/cgi-bin/token?${querystring.stringify(query)}`;
return await this.request(url);
}
/**
* 存储token
* @param {String} token
* @param {String} expires_in 在多少秒内过期,目前是7200秒
*/
saveToken(token, expires_in) {
this.store.put('deeply.nested', { access_token: token, expires: (new Date()).getTime() + expires_in * 1000 });
}
// 获取token
getToken() {
return { ...this.store.get('deeply.nested') };
}
/**
* 检查url是否被封禁
* @param {String} req_url 检查的url
*/
async check(req_url) {
try {
let url = await this.redirect(req_url);
return await this.checkDomainBanned(url);
} catch(err) {}
// try {
// const { access_token, expires } = this.getToken();
// // 为了避免acess_token过期,将阈值提前10分钟,否则重新获得token
// const paddingTime = 10 * 60 * 1000;
// if (typeof expires !== 'undefined' && ((new Date()).getTime() + paddingTime < expires)) {
// this.access_token = access_token;
// } else {
// const data = await this.getAccessToken();
// console.log('access_token', data.access_token)
// this.access_token = data.access_token;
// this.saveToken(this.access_token, data.expires_in);
// }
// let url = await this.createShortUrl(req_url);
// return await this.checkDomainBanned(url);
// } catch(err) {}
}
/**
* 通过微信api生成短链
* @param {String} req_url 待检测url
*/
async createShortUrl(req_url) {
var requestData = {
"access_token": this.access_token,
"action": "long2short",
"long_url": req_url
}
const url = `https://api.weixin.qq.com/cgi-bin/shorturl?access_token=${this.access_token}`;
let body = await this.request(url, {
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: requestData
});
return body && body.short_url;
}
/**
* 重定向处理
* @param {String} req_url 待检测的url
* @returns {String} res_url 返回的重定向链接
*/
async redirect(req_url) {
const url = `https://mp.weixinbridge.com/mp/wapredirect?url=${encodeURIComponent(req_url)}`;
const resUrl = await this.request(url, {
method: "GET",
});
return resUrl;
}
request(url, options = {}) {
return new Promise(function(resolve, reject) {
request(url, options, function(error, response, body) {
if (!error) {
try {
resolve(response?.request?.uri?.href || '');
} catch (err) {
resolve('');
}
// try {
// let json = {};
// if (typeof body === 'string') {
// json = JSON.parse(body);
// } else if (typeof body === 'object') {
// json = body;
// }
// resolve(json);
// } catch(err) {
// reject(err);
// }
}
})
});
}
/**
* 根据重定向之后的host是否为weixin110.qq.com来检测url是否被微信封禁
* @param {String} url 待检测短链接url
*/
checkDomainBanned(url) {
return new Promise(function (resolve, reject) {
return request(url, function(err, res, body) {
if (!err) {
if (res && res.request && res.request.uri && res.request.uri.host === 'weixin110.qq.com') {
resolve({ code: -1, msg: 'banned' });
} else {
resolve({ code: 0, msg: 'ok' });
}
} else {
reject(err);
}
})
})
}
}
module.exports = Checker;