关于微信签名signature获取

2017-09-13 20:37:27来源:cnblogs.com作者:zhangchenguang人点击

分享

微信分享的签名算法微信也写有,主要是调用接口需要使用服务器(微信官方文档是这么说的,试了下前端居然特么也可以),不过微信的access_token和jsapi_ticket是有使用次数限制的,所以还是用服务器来获取,得到以后存下来,下次使用判断超时以后再重新获取,这样就够用了,要不然就会出现接口调用次数超出限制这种尴尬的事情了。

如果需要使用自定义分享文案的时候,服务号或者订阅号一定要是已认证的(我的是个人类型的订阅号,不能认证,所以不能使用分享功能)

我这边用的是node做的后台,所以代码用的是js代码,当然其他的也可以,逻辑都一样,代码写法不一样而已。

1.首先是公众号的设置

  我这边申请的是一个订阅号

  首先,要在 开发 -> 基本配置 下,获取到自己的开发者id(appid)和开发者密码(AppSecret),这两个是必须的

  然后要在同目录下的 ip白名单 选项里设置好服务器的ip

  这样,基本服务器设置就算完成了。

2.然后就是我们最擅长的事了——写代码

  

  根据微信官方文档,第一步,我们需要拿到access_token,并且这个access_token有7200秒的有效期,所以拿到access_token以后要存在本地(文件存储或者数据库存储都可以,反正存好就行)

  具体实现代码如下

  首先需要引入node对应的模块(mongodb数据库每次使用还要启动,我嫌麻烦,所以我这边用的是文件存储)

    

1 var express=require('express');2 var https=require('https');5 var fs = require("fs");6 var crypto = require('crypto');

  从上往下依次是

    express模块 用来创建一个服务器,分别和前端、微信进行接口对接(在这里貌似没多大用,可以使用http模块代替)

    https模块 用来发送https请求的一个模块(微信请求需要使用https请求,http不行)

    fs模块 文件操作模块,如果是用的数据库就需要换成对应的模块

    crypto模块 加密模块,微信签名算法需要使用sha1算法加密,下边有说到

  模块全部引入,接下来定义一些方便使用的方法

  首先,要开启一个服务器:

 1 app.get("/getconfig",function (req,res) { 2     res.header("Access-Control-Allow-Origin", "*"); 3     res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); 4     res.header("Access-Control-Allow-Headers", "X-Requested-With"); 5     res.header('Access-Control-Allow-Headers', 'Content-Type'); 6     res.send({ 7                 code:"200", 8                 data:{}, 9                 result:true10             });11             res.end("");12 });13 app.listen(8000);

  然后定义阅读和写入文件的方法

 1 //写入文件 2 function whiteFile(obj,callback){ 3     fs.writeFile(obj.fileName,obj.data,{flag:"w"},function (err) { 4         if(err){ 5             console.error(obj.name+"文件写入错误"); 6             console.log(err); 7             return; 8         } 9         console.log('文件写入成功');10         callback(obj.data);11     });12 }13 //读取文件信息14 function readFile(obj,callback,errback){15     fs.readFile(obj.fileName,"utf-8",function (err,data) {16         if(err){17             console.error(obj.name+"读取错误");18             return errback(callback);19         }20         //console.log(data);21         if(!data){22             errback(callback);23         }else{24             console.log(data);25             callback(data);26         }27     });28 }

  然后是使用定义一个发送https请求的方法

 1 //发送一个http get请求 2 function sendGetRequest(options,callback){ 3     var httpReq=https.request(options, function(httpRes) { 4         httpRes.on('data',function(chun){ 5             callback(chun); 6         }); 7         httpRes.on('end',function(){}); 8     }); 9     httpReq.on('error',function(err){10         console.log("接口调用失败");11     });12     httpReq.end();13 }

  基本需要使用的方法有了,下边就可以请求微信接口了

 1 //获取access_token 2 function getToken(callback){ 3     readFile({ 4         fileName:"./access_token.txt", 5         name:"access_token" 6     },callback,function(cb){ 7         var options={ 8             hostname:"api.weixin.qq.com", 9             path:"/cgi-bin/token?grant_type=client_credential&appid=您的appid&secret=你的appid对应的密码",10             method:'GET'11         };12         sendGetRequest(options,function(chun){13             var resObj = JSON.parse(chun.toString());14             resObj.timestamp = Math.floor((new Date().getTime())/1000);15             var res = JSON.stringify(resObj);16             //console.log(res);17             try {18                 whiteFile({19                     fileName:"./access_token.txt",20                     data:res,21                     name:"access_token"22                 },cb);23             }catch(err){24                 console.log("文件写入失败");25                 console.log("access_token:"+res);26                 cb(res);27             }28         });29     });30 }
  上边这个方法是获取微信token的方法,我这边首先从本地文件中读取,读取不到再调用接口(我这里只是测试使用,没有做判断,实际操作中需要判断时间戳,如果access_token过期需要删掉文件里的内容重新请求新的access_token)

  access_token有了,下边就是获取jsapi_ticket:

 1 //获取ticket 2 function getTicket(callback){ 3     readFile({ 4         fileName:"./ticket.txt", 5         name:"ticket" 6     },callback,function(cb) { 7         getToken(function(tokenData){ 8             var token = JSON.parse(tokenData); 9             //console.log("token:"+JSON.stringify(token));10             //callback({code:"200",data:{"data":token},result:true});11             var options = {12                 hostname: "api.weixin.qq.com",13                 path: "/cgi-bin/ticket/getticket?access_token=" + token.access_token + "&type=jsapi",14                 method: 'GET'15             };16             sendGetRequest(options, function (chun) {17                 var resObj = JSON.parse(chun.toString());18                 resObj.timestamp = Math.floor((new Date().getTime())/1000);19                 var res = JSON.stringify(resObj);20                 if (resObj.errcode == 42001) {21                     getToken(function(){22                         getTicket(callback);23                     });24                 } else if (resObj.ticket) {25                     try {26                         whiteFile({27                             fileName:"./ticket.txt",28                             data:res,29                             name:"ticket"30                         },callback);31                     }catch(err){32                         console.log("文件写入失败");33                         console.log("ticket:"+res);34                         callback(res);35                     }36                 } else {37                     callback(res);38                 }39 40             });41         });42     });43 }

  jsapi_ticket和token获取和存储逻辑是一样的

  

  接下来就是签名的生成

 1 getTicket(function(data){ 2             var dataObj = JSON.parse(data); 3             var noncestr = "zhangchenguang"; 4             var timestamp = Math.floor((new Date().getTime())/1000); 5             var url = "http://api-loan.zhmf.com/html/test/testshare.html"; 6             var obj = { 7                 noncestr,timestamp,url,jsapi_ticket:dataObj.ticket 8             }; 9             var arr = ["noncestr","jsapi_ticket","timestamp","url"].sort();10             var string1 = "";11             for(var i = 0; i < arr.length; i++){12                 string1 += (arr[i]+"="+obj[arr[i]])+"&";13             }14             string1 = string1.slice(0,string1.length-1);15             console.log(string1);16             var shasum = crypto.createHash('sha1');17             shasum.update(string1);18             var signature = shasum.digest("hex");19             console.log(signature);20         });

  生成签名以后,把签名和随机串和appid和时间戳同时通过res.send传给前端:

 1 app.get("/getconfig",function (req,res) { 2     res.header("Access-Control-Allow-Origin", "*"); 3     res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); 4     res.header("Access-Control-Allow-Headers", "X-Requested-With"); 5     res.header('Access-Control-Allow-Headers', 'Content-Type'); 6         getTicket(function(data){ 7             var dataObj = JSON.parse(data); 8             var noncestr = "zhangchenguang"; 9             var timestamp = Math.floor((new Date().getTime())/1000);10             var url = "http://api-loan.zhmf.com/html/test/testshare.html";11             var obj = {12                 noncestr,timestamp,url,jsapi_ticket:dataObj.ticket13             };14             var arr = ["noncestr","jsapi_ticket","timestamp","url"].sort();15             var string1 = "";16             for(var i = 0; i < arr.length; i++){17                 string1 += (arr[i]+"="+obj[arr[i]])+"&";18             }19             string1 = string1.slice(0,string1.length-1);20             console.log(string1);21             var shasum = crypto.createHash('sha1');22             shasum.update(string1);23             var signature = shasum.digest("hex");24             console.log(signature);25             res.send({26                 code:"200",27                 data:{28                     noncestr:noncestr,29                     timestamp:timestamp,30                     appId:"wx23599cdec409383c",31                     signature:signature32                 },33                 result:true34             });35             res.end("");36         });37 });

  前端接收到数据后调用wx.config(),并传入对饮的参数就可以获取到对应的微信js权限了(前端实现逻辑上篇随笔写过了)。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台