最近用到了微信sdk 的分享功能需要生成签名
一、大致流程如下
1. 调用`api.weixin.qq.com/cgi-bin/tok… 生成`access_token`
2. 拿到token 后调用`api.weixin.qq.com/cgi-bin/tic… 获取`jsapi_ticket`
3. 用ticket 再去利用sha1 算法生成签名
二、遇到的坑有
1. 后台用koa搭建的服务,在接口里调用微信的服务 因为请求是异步的 会出现`ctx.body` 拿不到返回结果 先于请求执行了 这时候就用到了`promise`。
2. 签名无效
a:用于生成签名的url 前端传递 要动态 获取并用`encodeURIComponent` 编码 后台拿到后再用`encodeURIComponent` 去解码
三、 签名有效期为2h 所以需要缓存toekn, 这里采用的是将token等信息以文件形式缓存 每次去读取上次文件生成的时间 看是否过期 决定是重新请求还是直接读取上次文件内容。
四、代码实现
1、后台
router.get('/signatureInit',async (ctx) => { const query = ctx.query; let nowTime = parseInt(new Date().getTime()/1000); let signTimer = signJson.timer?signJson.timer:null let filePath = path.join('/usr/local/nodeServe/mtnode', '/config', 'sign.json'); let url = decodeURIComponent(query.url) if (signTimer == null || (nowTime - signTimer) > 7200) { console.log('请求重新更新') let url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=' + query.grant_type + '&appid=' + query.appid + '&secret=' + query.secret + '&url=' + url; let ticketUrl, signStr; let accessToken = await new Promise((resolve, reject) => { request(url, (err, res, body) => { if (res) { resolve(body) } else { reject(err) } }) }) ticketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=' + JSON.parse(accessToken).access_token; let ticketData = await new Promise((resolve, reject) => { request(ticketUrl, (err, res, body) => { if (res) { resolve(body) } else { reject(err) } }) }) signStr = Sign(JSON.parse(ticketData)['ticket'], url); signStr.timestamp = + signStr.timestamp let data = { ...signStr, timer:parseInt(new Date().getTime()/1000) } fs.writeFile(filePath, JSON.stringify(data), (err) => { if (err) { console.log(err) } else { console.log('文件保存成功') } }) ctx.response.status = 200; ctx.body = ctx.body = { ...signJson, type:'new', query:query, access_token:JSON.parse(accessToken).access_token } } else { console.log('还没过期那啊') ctx.response.status = 200; ctx.body = { ...signJson, type:'old', query:query } } })
2、 前端
var that = this; var url = "http://localhost:3000/signatureInit", appid="", secret='', urllink = encodeURIComponent(window.location.href.split('#')[0]); console.log(urllink) url += '?grant_type=client_credential&appid='+appid+'&secret='+ secret +'&url=' + urllink var xhr = new XMLHttpRequest() xhr.open("GET",url,true) xhr.responseType = 'text'; xhr.send() xhr.onreadystatechange = function(e) { if(xhr.readyState==4 && xhr.status == 200){ let response = JSON.parse(xhr.responseText) initShare(response) } } function initShare(data){
..............
............
...........
分享功能
}