微信公众号开发之消息收发

一, 服务器有效性验证

  • 首先参考:微信公众号接入服务器指南.进行配置一些服务器的信息
  • 微信开放文档未提供node版的验证服务器地址有效性的代码示例,此代码也可通过微信提供的其他代码示例来写出node版示例。
       var crypto = require("crypto");
       function sha1(str){
         var md5sum = crypto.createHash("sha1");
         md5sum.update(str);
         str = md5sum.digest("hex");
         return str;
       }
       
       function validateToken(req,res){
         var query = req.query;//express创建的服务器
         //var query = url.parse(req.url,true).query;//通过http创建的服务器
         console.log(query);
         var signature = query.signature;//微信加密签名
         var echostr = query.echostr;//随机字符串
         var timestamp = query['timestamp'];//时间戳
         var nonce = query.nonce;//随机数
         var oriArray = new Array();
       	  oriArray[0] = nonce;
       	  oriArray[1] = timestamp;
       	  oriArray[2] = "myserty";//这里是你在微信开发者中心页面里填的token
       	//1.将token、timestamp、nonce三个参数进行字典序排序
       	  oriArray.sort();
         var original = oriArray.join('');//把排序后的数组转换为字符串
         //2.将三个参数字符串拼接成一个字符串进行sha1加密
         var scyptoString = sha1(original);
       	  //3.开发者获得加密后的字符串与signature对比,判断该请求是否来源于微信
       	  if(signature == scyptoString){
       	  	//4.若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
       	    res.end(echostr);
       	  }else {
       	    res.end("false");
       	  }
       }
       module.exports = {
       	validateToken
       };
    
    	var express = require('express');
    	var router = express.Router();
    	const { validateToken } = require('../utils/weixin.js');
    	router.get('/', function(req, res) {
    		validateToken(req,res);
    	});
    
  • 参考地址:
    node版示例代码
    express服务器快速创建
  • 我提炼出的过程为:
    1. 微信服务器根据开发者填写的token参数,请求中的timestamp参数nonce参数,进行加密生成signature签名
    2. 微信服务器将发送GET请求到开发者提供的服务器地址URL上,并携带signature参数(微信加密签名)timestamp参数(时间戳)nonce参数(随机数)echostr参数(随机字符串)
    3.  示例:GET /?signature=0c1f56bb94241393e83fe733379ba9bcb2d94d09&echostr=5735277558564388844&timestamp=1584954856&nonce=441827227 200 15.850 ms - -
      
    4. 根据微信校验流程:
      • tokentimestampnonce三个参数进行字典序排序
      • 将三个参数字符串拼接成一个字符串进行sha1加密
      • 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
      • 对比成功后,原样返回echostr参数内容
      • 微信服务器收到之后,如果等于服务器本身设定的那个值,就通过验证。

二,消息的收发

  • 当微信用户向公众号账号发送消息时,微信服务器将POST消息的XML数据包发送到开发者填写的URL
    <xml>
    <!--发送的xml数据包格式-->
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>1348831860</CreateTime>
      <MsgType><![CDATA[text]]></MsgType>
      <Content><![CDATA[this is a test]]></Content>
      <MsgId>1234567890123456</MsgId>
    </xml>
    <!--toUser:开发者微信号-->
    <!--fromUser:发送方帐号(一个OpenID)-->
    <!--CreateTime:消息创建时间 (整型)-->
    <!--MsgType:消息类型,文本为text-->
    <!--Content:文本消息内容-->
    <!--MsgId:消息类型,消息id,64位整型-->
    
  • 示例代码:
    <xml>
     	<ToUserName><![CDATA[gh_9afe90ec****]]></ToUserName>
        <FromUserName><![CDATA[o91bkwKk8n3dIxoad6sfHhUL****]]></FromUserName>
        <CreateTime>1584957185</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[HR]]></Content>
        <MsgId>22691129132250277</MsgId>
    </xml>
    
  • 之前通过body-parserreq.body直接获取微信传递过来的数据包XML),发现获取不到(为一个空对象),原因是body-parser只对req.body 为json格式的做解析,所以对于xml格式的,解析后就req.body就变成空对象了。
  • 通过百度查找到了两个xml转化模块:xml2jsexpress-xml-bodyparser
  • 因为我使用的为express,而且只需要在请求中调用转换,所以选择express-xml-bodyparser
    function sendMsg(req,res){
     var query = req.body.xml;
     console.log(query);
     let msg = `
       <xml>
         <ToUserName><![CDATA[${query.fromusername}]]></ToUserName>
         <FromUserName><![CDATA[${query.tousername}]]></FromUserName>
         <CreateTime>${query.timestamp}</CreateTime>
         <MsgType><![CDATA[text]]></MsgType>
         <Content><![CDATA[你好]]></Content>
       </xml>
       `
       /*
       ToUserName:接收方帐号
       FromUserName:开发者微信号
       CreateTime:消息创建时间 (整型)
       MsgType:消息类型,文本为text
       Content:文本消息内容
    */
       //注意返回的数据也必须为XML结构
       res.end(msg);
    }
    
    module.exports = {
       sendMsg
    };
    
    var express = require('express');
    var xmlparser = require('express-xml-bodyparser');
    var router = express.Router();
    const { sendMsg } = require('../utils/wei.js');
    router.post('你设置的公众号URL',xmlparser({trim: false, explicitArray: false}), function(req, res) {
     sendMsg(req,res);
    });
    
    通过express-xml-bodyparser解析后的数据包
    {
      tousername: 'gh_9afe90ec****',
      fromusername: 'o91bkwKk8n3dIxoad6sfHhUL****',
      createtime: '1584958735',
      msgtype: 'text',//消息类型
      content: '你好',//发送的消息内容
      msgid: '22691153806695561'
    }
    

三,其他消息类型及返回结构参考微信开放文档

微信开放文档

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值