Node.js 微信公众号-基本配置-服务器URL

1、验证签名

在提交配置时,服务器对应的URL需要实现签名的验证,成功时,需要直接返回 echostr 的值,注意此时URL对应的接口为get请求

                        const { signature, timestamp, nonce, echostr  } = _req.query;

                        const token = "my_token"; // 公众号配置时的Token

                        const tmpArr = [token, timestamp, nonce];

                        tmpArr.sort();

                        // 引入加密模块

                        const crypto = require('crypto');

                        // 创建哈希对象

                        const sha1Hash = crypto.createHash('sha1');

                        // console.log("排序后连接:", tmpArr.join(""))

                        sha1Hash.update(tmpArr.join(""));

                        const hashedData = sha1Hash.digest('hex');

                        // console.log(hashedData, signature);

                        if (hashedData == signature) {

                                res.end(echostr);

                        }

2、消息推送

在用户操作时(关注、取消关注、扫描公众号二维码码等操作时),微信公众号会发送消息到基本配置中的URL对应的接口,注意此时URL对应的接口为post请求,也就是说URL对应的接口需要同时支持get和post请求。而且需要在IP白名单中添加服务器的IP地址

3、完整示例

// router.js

var api = require('./api')

const bodyParser = require('body-parser')

const xmlParser = bodyParser.text({type: 'text/xml'});

// 验证微信公众号基本配置的URL

router.get('/receiveWeixinData', (req, res, next) => {

  api.receiveWeixinData(req, res, next);

})

// 接收微信公众号推送过来的事件消息,和验证是同一个接口,不过使用的是post请求

router.post('/receiveWeixinData', xmlParser, (req, res, next) => {

  api.receiveWeixinData(req, res, next);

})

// api.js

// 公众号基本配置URL

async receiveWeixinData(_req, res, _next) {

  if (_req.query && _req.query["echostr"]) { // 用于配置时验证

          // console.log("get验证接收到的参数:", _req.query);

          const { signature, timestamp, nonce, echostr } = _req.query;

          const token = "my_token"; // 公众号配置时的token

          const tmpArr = [token, timestamp, nonce];

          tmpArr.sort();

          // 引入加密模块

          const crypto = require('crypto');

          // 创建哈希对象

          const sha1Hash = crypto.createHash('sha1');

          sha1Hash.update(tmpArr.join(""));

          const hashedData = sha1Hash.digest('hex');

          if (hashedData == signature) {

                  res.end(echostr);

          } else {

                  res.end(false);

          }

  } else { // 用于平时扫码接收和发送消息

          const xml = _req.body;

          const xml2js = require('xml2js'); // xml2js需要npm先安装

          xml2js.parseString(xml, { trim: true }, async (err, result) => {

                  if (err) {

                          console.error(err);

                          res.status(500).send('Internal Server Error');

                          return;

                  }

                  const message = result.xml;

                  // console.log("推送消息:", message)

                  let time = Math.floor(new Date().getTime() / 1000);

                  let content = '登录成功,欢迎使用简单设计!';

                  if (message.MsgType[0] === 'event') {

                          // 处理事件推送

                          const eventType = message.Event[0];

                          let eventKey = message.EventKey[0]; // 这个是获取公众号二维码的时候定义的,在获取ticket的时候,传给公众号接口就可定义这个scene_str

                          let user_id = message.FromUserName[0];

                          let checkRes = '';

                          switch (eventType) {

                                  case 'subscribe':

                                          // 处理关注事件

                                        console.log('首次关注')

                                          break;

                                  case 'unsubscribe':

                                          // 处理取消关注事件

                                          console.log('取消关注')

                                          break;

                                  case 'SCAN':

                                          // 关注后的扫码,前面会带qrscene_前缀

                                          if (eventKey.includes('qrscene_')) {

                                                  eventKey = eventKey.replace('qrscene_', '');

                                          }

                                         console.log("扫码了")

                                          break;

                          }

                  }

                  // 这个是扫码后,在公众号回复给用户看的,注意ToUserName是接收时的FromUserName,FromUserName是接收时的ToUserName

                  let returnXml =

                          `<xml><ToUserName><![CDATA[${message.FromUserName[0]}]]></ToUserName>

                          <FromUserName><![CDATA[${message.ToUserName[0]}]]></FromUserName>

                          <CreateTime>${time}</CreateTime>

                          <MsgType><![CDATA[text]]></MsgType>

                          <Content><![CDATA[登录成功,欢迎使用简单设计!]]></Content>

                          </xml>`;

                  res.send(returnXml);

          });

  }

},

体验参考:简单设计EasyDesign-免费在线设计工具图片处理工具icon-default.png?t=N7T8https://jiandan.link/#/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QmagicianRX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值