Showing
1 changed file
with
71 additions
and
6 deletions
1 | +'use strict'; | ||
2 | + | ||
3 | +/* | ||
4 | + * 生成微信分享所需的签名 | ||
5 | + * bikai <kai.bi@yoho.cn> | ||
6 | + * 2016.6.15 | ||
7 | + */ | ||
1 | const request = require('request-promise'); | 8 | const request = require('request-promise'); |
2 | const Promise = require('bluebird'); | 9 | const Promise = require('bluebird'); |
10 | +const crypto = require('crypto'); | ||
3 | const logger = require('../../../library/logger'); | 11 | const logger = require('../../../library/logger'); |
12 | +const cache = require('../../../library/cache'); | ||
13 | + | ||
14 | +const appId = 'wx75e5a7c0c88e45c2'; | ||
15 | +const secret = 'ce21ae4a3f93852279175a167e54509b'; | ||
16 | + | ||
17 | +const sha1 = (etr) => { | ||
18 | + const generator = crypto.createHash('sha1'); | ||
19 | + | ||
20 | + generator.update(etr); | ||
21 | + return generator.digest('hex'); | ||
22 | +}; | ||
23 | + | ||
24 | +const accessTokenCacheKey = 'wechatShare:accessToken'; | ||
25 | +const ticketCacheKey = 'wechatShare:ticket'; | ||
4 | 26 | ||
5 | -const appId = ''; | ||
6 | -const secret = ''; | 27 | +// 微信 JS 接口签名校验工具 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign |
7 | 28 | ||
8 | const wechat = { | 29 | const wechat = { |
9 | getAccessToken: Promise.coroutine(function* () { | 30 | getAccessToken: Promise.coroutine(function* () { |
31 | + let accessToken = yield cache.get(accessTokenCacheKey); | ||
32 | + | ||
33 | + if (accessToken) { | ||
34 | + return accessToken; | ||
35 | + } | ||
36 | + | ||
37 | + logger.info('调用微信 API 获取 accessToken'); | ||
10 | return request({ | 38 | return request({ |
11 | url: 'https://api.weixin.qq.com/cgi-bin/token', | 39 | url: 'https://api.weixin.qq.com/cgi-bin/token', |
12 | qs: { | 40 | qs: { |
13 | grant_type: 'client_credential', | 41 | grant_type: 'client_credential', |
14 | appid: appId, | 42 | appid: appId, |
15 | secret: secret | 43 | secret: secret |
16 | - } | 44 | + }, |
45 | + json: true | ||
46 | + }).then((res) => { | ||
47 | + | ||
48 | + // accessToken 有效期 7200s,缓存 7100s | ||
49 | + cache.set(accessTokenCacheKey, res.access_token, 7100).catch((err) => { | ||
50 | + logger.error('微信分享 Token, 缓存 accessToken 时出错', JSON.stringify(err)); | ||
51 | + }); | ||
52 | + return res.access_token; | ||
17 | }).catch((err) => { | 53 | }).catch((err) => { |
18 | logger.error('微信分享 Token, 获取 accessToken 时出错', JSON.stringify(err)); | 54 | logger.error('微信分享 Token, 获取 accessToken 时出错', JSON.stringify(err)); |
19 | }); | 55 | }); |
20 | }), | 56 | }), |
21 | 57 | ||
22 | getTicket: Promise.coroutine(function* (accessToken) { | 58 | getTicket: Promise.coroutine(function* (accessToken) { |
59 | + let ticket = yield cache.get(ticketCacheKey); | ||
60 | + | ||
61 | + if (ticket) { | ||
62 | + return ticket; | ||
63 | + } | ||
64 | + | ||
65 | + logger.info('调用微信 API 获取 ticket'); | ||
23 | return request({ | 66 | return request({ |
24 | url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket', | 67 | url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket', |
25 | qs: { | 68 | qs: { |
26 | access_token: accessToken, | 69 | access_token: accessToken, |
27 | type: 'jsapi' | 70 | type: 'jsapi' |
28 | - } | 71 | + }, |
72 | + json: true | ||
73 | + }).then(res => { | ||
74 | + | ||
75 | + // ticket 有效期 7200s,缓存 7100s | ||
76 | + cache.set(ticketCacheKey, res.ticket, 7100).catch((err) => { | ||
77 | + logger.error('微信分享 Token, 缓存 ticket 时出错', JSON.stringify(err)); | ||
78 | + }); | ||
79 | + return res.ticket; | ||
29 | }).catch((err) => { | 80 | }).catch((err) => { |
30 | logger.error('微信分享 Token, 获取 ticket 时出错', JSON.stringify(err)); | 81 | logger.error('微信分享 Token, 获取 ticket 时出错', JSON.stringify(err)); |
31 | }); | 82 | }); |
32 | }), | 83 | }), |
33 | 84 | ||
34 | - calcSignature: Promise.coroutine(function* () { | ||
35 | - return yield Promise.resolve(true); | 85 | + calcSignature: Promise.coroutine(function* (data) { |
86 | + let accessToken = yield this.getAccessToken(); | ||
87 | + | ||
88 | + data = Object.assign({ | ||
89 | + noncestr: Math.random().toString(36).substr(2, 15), | ||
90 | + timestamp: Math.floor(Date.now() / 1000) + '', | ||
91 | + ticket: yield this.getTicket(accessToken) | ||
92 | + }, data); | ||
93 | + const str = `jsapi_ticket=${data.ticket}&noncestr=${data.noncestr}×tamp=${data.timestamp}&url=${data.url}`; | ||
94 | + | ||
95 | + return sha1(str); | ||
36 | }) | 96 | }) |
37 | }; | 97 | }; |
38 | 98 | ||
99 | +// 测试 | ||
100 | +// wechat.calcSignature({ | ||
101 | +// url: 'http://www.yohobuy.com/boys' | ||
102 | +// }).then(console.log); | ||
103 | + | ||
39 | module.exports = wechat; | 104 | module.exports = wechat; |
-
Please register or login to post a comment