const request = require('request')const express = require('express')const app = express()const sha1 = require('sha1')const waterfall = require('async/waterfall')const NodeCache = require('node-cache')const cache = new NodeCache({stdTTL: 3600, checkperiod: 3600}) //3600秒后过过期app.get('/wxJssdk', (req, res) => {
let wx = req.query
// 1)将token、timestamp、nonce三个参数进行字典序排序
let token = 'jegfjaeghfuyawegfgjdbh'
let timestamp = wx.timestamp
let nonce = wx.nonce
// 2)将三个参数字符串拼接成一个字符串进行sha1加密
let list = [token, timestamp, nonce] let result = sha1(list.sort().join('')) // 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if (result === wx.signature) {res.send(wx.echostr) } else {res.send(false) }})app.get('/wxJssdk/getJssdk', (req, res) => {
let grant_type = 'client_credential'
let appid = 'your app id'
let secret = 'your app secret' // appscret
let steps = [] // 第一步,获取access_token
steps.push((cb) => {
let steps1 = []// 第1.1步,从缓存中读取access_tokensteps1.push((cb1) => { let access_token = cache.get('access_token', (err, access_token) => {cb1(err, access_token) })})// 第1.2步,缓存中有access_token则直接返回,如果没有,则从服务器中读取access_tokensteps1.push((access_token, cb1) => { if (access_token) {cb1(null, access_token, 'from_cache') } else {request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { cb1(err, JSON.parse(body).access_token, 'from_server')}) }})// 第1.3步,如果是新从服务器取的access_token,则缓存起来,否则直接返回steps1.push((access_token, from_where, cb1) => { if (from_where === 'from_cache') {console.log(' === 成功从缓存中读取access_token: ' + access_token + ' ===')cb1(null, access_token) } else if (from_where === 'from_server') {cache.set('access_token', access_token, (err, success) => { if (!err && success) {console.log(' === 缓存已过期,从服务器中读取access_token: ' + access_token + ' ===')cb1(null, access_token) } else {cb1(err || 'cache设置access_token时,出现未知错误') }}) } else {cb1('1.3获取from_where时,from_where值为空') }})waterfall(steps1, (err, access_token) => { cb(err, access_token)}) }) // 第二步,获取ticket
steps.push((access_token, cb) => {let steps1 = []// 第2.1步,从缓存中读取ticketsteps1.push((cb1) => { let ticket = cache.get('ticket', (err, ticket) => {cb1(err, ticket) })})// 第2.2步,缓存中有ticket则直接返回,如果没有,则从服务器中读取ticketsteps1.push((ticket, cb1) => { if (ticket) {cb1(null, ticket, 'from_cache') } else {request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', (err, response, body) => { cb1(err, JSON.parse(body).ticket, 'from_server')}) }})// 第2.3步,如果新从服务器取的ticket,则缓存起来,否则直接返回steps1.push((ticket, from_where, cb1) => { if (from_where === 'from_cache') {console.log(' === 成功从缓存中读取ticket: ' + ticket + ' ===')cb1(null, ticket) } else if (from_where === 'from_server') {cache.set('ticket', ticket, (err, success) => { if (!err && success) {console.log(' === 缓存已过期,从服务器中读取ticket: ' + ticket + ' ===');cb1(null, ticket) } else {cb1(err || 'cache设置ticket时,出现未知错误') }}) } else {cb1('2.3获取from_where时,from_where值为空') }})waterfall(steps1, (err, ticket) => { cb(err, ticket)}) }) // 第三步,生成签名
steps.push((ticket, cb) => {let jsapi_ticket = ticketlet nonce_str = '123456'let timestamp = new Date().getTime()let url = req.query.urllet str = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + nonce_str + '×tamp=' + timestamp + '&url=' + urllet signature = sha1(str)cb(null, { appId: appid, timestamp: timestamp, nonceStr: nonce_str, signature: signature, ticket: ticket}) }) waterfall(steps, (err, data) => {if (err) { res.send({status: 'error', data: err})} else { res.send({status: 'success', data: data})}
})})app.use('/wxJssdk/public', express.static('public'))app.listen(80, err => {
if(!err) console.log('connect succeed')})
ログイン後にコピー