使用node.js接入微信公众号开发

2022-08-22 09:52:24 浏览数 (1)

前言

前阵子开始搞起了公众号,摸索期间也接触到了公众号开发,特将摸索过程中经历记录下来和大家分享,由于没有经历过系统的后端学习,所以以下步骤及思路均为个人在网上摸索以及思考整理而出,不保证权威性,仅供参考,如有错误或可以改进的地方,欢迎提出。

接入流程-微信侧

首先我们登录公众号后台,找到左侧菜单中的基本设置

点击修改配置之后,我们会进入参数填写页

下面我们对每一个参数进行分析。

参数说明

URL

必须以http://https://开头,分别支持80端口和443端口。这里就是要我们填入我们的后端地址,用户的操作类请求微信都会给转发到这个地址,需要注意的是这个地址仅支持80端口和443端口,所以我们有两种方法

  • 将给后端服务分配一个单独的子域名(二级、三级均可),本文采取的就是这种方法
  • 使用Nginx进行代理,如果你的后端服务没有使用80端口或者443端口,可以使用Nginx将请求转发到后端所在的地址。
Token

Token可由我们任意填写,主要是用来生成签名,我们在初始接入的时候,微信会利用token生成秘钥发送给服务器,服务器对秘钥进行验证,验证成功即可接入成功。

EncodingAESKey

EncodingAESKey可以由我们手写,或者点击随机生成按钮进行生成,这个主要用户后期的微信发送到服务器的消息体的加解密,后面我们会说到。

消息加解密方式
  • 明文模式:不加密
  • 兼容模式:加密不加密共存
  • 安全模式:加密

由于本篇文章不涉及后续的消息处理,暂时不讲,后面讲消息处理的时候会说到,开发时我们选择兼容模式即可

接入流程-服务器侧

服务器验证

全部填写完毕,我们点击提交,会发现系统弹出了错误弹窗,告诉我们token验证失败

这是因为我们仅在微信这边配置了,但是没有在服务器端进行回应。我们先来看看服务端有没有收到消息

可以看到我们已经收到了微信的验证消息,下面我们只要对微信进行正确的回应就好了。

首先我们要知道微信发送的这串消息都涵盖了哪些参数,都是什么意思,我们需要怎么回应。

微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示

参数

描述

signature

微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

timestamp

时间戳

nonce

随机数

echostr

随机字符串

signature有我们之前填写的token和微信get请求中的timestamp、nonce共同组合加密而成,我们收到之后需要对signature进行解码,然后对解码出来的token进行验证 ,验证完成之后返回echostr参数给微信即可完成接入。

signature的加密规则如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序
  2. 将三个参数字符串拼接成一个字符串进行sha1加密

字典序排序其实就是按字母顺序排序,我们使用js中数组的sort方法即可。

接下来我们要在服务端对请求进行处理,来完成接入流程。

因为我们之前在微信填写的服务端地址为域名/wx,所以我们先把/wx这个路由的请求放到白名单中,不进行权限校验。

上面我们说了,signature的加密规则用到了sha1加密,这里我们可以使用node.js自带的方法来实现一个sha1加密

代码语言:javascript复制
// encryption.js
const crypto = require('crypto')

module.exports = {
  md5: (str) => {
    return crypto.createHash('md5').update(str).digest('hex')
  },
  sha1: (str) => {
    return crypto.createHash('sha1').update(str).digest('hex')
  }
}

之后我们就可以对微信的验证消息进行验证并处理了

代码语言:javascript复制
const encryption = require('../utils/encryption')
class WxController {
  async index(ctx) {
    let {signature = '', timestamp = '', nonce = '', echostr = ''} = ctx.query
    let token = process.env.wx_token

    // 验证token
    let str = [token, timestamp, nonce].sort().join('')
    let sha1 = encryption.sha1(str)
    if (sha1 !== signature) {
      ctx.body = 'token验证失败'
      return
    } else {
      ctx.body = echostr
    }
  }
}

module.exports = new WxController()

改完之后我们部署到服务器,然后再去微信侧点击一下提交,可以看到,已经可以提交成功了。

之后我们点击启用按钮,会提示我们启用之后公众平台的自定义菜单和自动回复将会失效,所有的请求都会转发到我们自己的服务端

之后我们去公众号测试一下

会发现微信提示我们公众号服务故障,这是因为我们还没有对发送的消息做任何处理,然后我们去服务端看看

可以看到我们已经成功的收到了微信转发过来的请求,说明我们已经接入成功了,后面只需要按微信的规定,对信息进行处理,然后返回必要的信息就可以了,这些就放在后面的文章说吧。

顺便吐槽一句,个人公众号的权限真少啊

0 人点赞