zoukankan      html  css  js  c++  java
  • 关于微信签名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权限了(前端实现逻辑上篇随笔写过了)。

  • 相关阅读:
    茗洋ASP.NET MVC4 IN ACTION 教程目录
    C#实验室<群内活动>2013年5月12日的算法题目记录[胜者:Yamat]
    那天有个小孩跟我说LINQ(四)
    C#实验室同盟测试iframe
    C#实验室同盟测试页
    那天有个小孩跟我说LINQ(五)
    C#实验室<常用软件>Windows Live Writer
    ASP.NET MVC4 IN ACTION学习笔记第六波[Ajax in ASP.NET MVC][1/3]
    那天有个小孩跟我说LINQ(六)
    ASP.NET MVC4 IN ACTION学习笔记第四波
  • 原文地址:https://www.cnblogs.com/zchenguang/p/7515513.html
Copyright © 2011-2022 走看看