前言
前阵子开始搞起了公众号,摸索期间也接触到了公众号开发,特将摸索过程中经历记录下来和大家分享,由于没有经历过系统的后端学习,所以以下步骤及思路均为个人在网上摸索以及思考整理而出,不保证权威性,仅供参考,如有错误或可以改进的地方,欢迎提出。
接入流程-微信侧
首先我们登录公众号后台,找到左侧菜单中的基本设置
点击修改配置之后,我们会进入参数填写页
下面我们对每一个参数进行分析。
参数说明
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的加密规则如下:
- 将token、timestamp、nonce三个参数进行字典序排序
- 将三个参数字符串拼接成一个字符串进行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()
改完之后我们部署到服务器,然后再去微信侧点击一下提交,可以看到,已经可以提交成功了。
之后我们点击启用按钮,会提示我们启用之后公众平台的自定义菜单和自动回复将会失效,所有的请求都会转发到我们自己的服务端
之后我们去公众号测试一下
会发现微信提示我们公众号服务故障,这是因为我们还没有对发送的消息做任何处理,然后我们去服务端看看
可以看到我们已经成功的收到了微信转发过来的请求,说明我们已经接入成功了,后面只需要按微信的规定,对信息进行处理,然后返回必要的信息就可以了,这些就放在后面的文章说吧。
顺便吐槽一句,个人公众号的权限真少啊