關於微信簽名signature獲取


微信分享的簽名算法微信也寫有,主要是調用接口需要使用服務器(微信官方文檔是這么說的,試了下前端居然特么也可以),不過微信的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:true
10             });
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.ticket
13             };
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:signature
32                 },
33                 result:true
34             });
35             res.end("");
36         });
37 });

 

  前端接收到數據后調用wx.config(),並傳入對飲的參數就可以獲取到對應的微信js權限了(前端實現邏輯上篇隨筆寫過了)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM