这是一个简单的用Node.js开发微信墙的教程,在这个教程中,包括以下几部分内容:
- 验证服务器有效性
- 接收用户通过微信订阅号发给服务器的消息
- 解析收到的XML文本消息格式为JSON
- 用模板构造应答用户的XML文本消息
- 将接收到的消息通过WebSocket服务广播
- 获取消息发送人的用户基本信息(名字和头像)
微信服务大体上分为两类,一类是消息服务,一类是数据服务。
消息服务是由用户在微信服务号中发送消息,然后微信服务讲消息推送给开发者服务器,因此它是由微信主动发起,开发者服务器被动接收的。
消息服务的数据体格式是XML,微信服务与开发者服务器之间通过约定token保证数据传输的真实和有效性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//verify.js var PORT = 9529; var http = require("http"); var qs = require("qs"); var TOKEN = "yuntu"; function checkSignature(params, token){ //1. 将token、timestamp、nonce三个参数进行字典序排序 //2. 将三个参数字符串拼接成一个字符串进行sha1加密 //3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 var key = [token, params.timestamp, params.nonce].sort().join(""); var sha1 = require("crypto").createHash("sha1"); sha1.update(key); return sha1.digest("hex") == params.signature; } var server = http.createServer(function (request, response) { //解析URL中的query部分,用qs模块(npm install qs)将query解析成json var query = require("url").parse(request.url).query; var params = qs.parse(query); console.log(params); console.log("token-->", TOKEN); if(checkSignature(params, TOKEN)){ response.end(params.echostr); }else{ response.end("signature fail"); } }); server.listen(PORT); console.log("Server runing at port: " + PORT + "."); |
事实上,token验证仅用来给开发者服务器验证消息来源确实是微信,而不是伪造的(因为别人不知道具体的token),作为消息发起方的微信并不要求必须验证,也就是说,开发者也可以偷懒不做验证(后果是别人可以模仿微信给服务post请求)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//noverify.js /** TOKEN 校验是保证请求的真实有效,微信自己并不校验TOKEN, 开发者服务器也可以不校验直接返回echostr, 但是这样的话意味着第三方也可以很容易伪造请求假装成微信发送给开发者服务器 */ var PORT = 9529; var http = require("http"); var qs = require("qs"); var server = http.createServer(function (request, response) { var query = require("url").parse(request.url).query; var params = qs.parse(query); response.end(params.echostr); }); server.listen(PORT); console.log("Server runing at port: " + PORT + "."); |
将微信服务号的服务器配置为开发服务器的URL,就可以接收到微信服务号的消息了
注意:其实理论上一个服务器可以接受和处理多个服务号/订阅号的消息,可以通过消息体的ToUserName来加以区别这个消息是发给哪个微信号的