微信sdk 生成签名

95 阅读1分钟

最近用到了微信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){
..............
............
...........
分享功能
}