ThinkJS 接入微信公众平台 1 —— Token 服务器验证

微信公众平台配置

进入微信公众号的后台,点击左侧菜单 《开发》->《基本配置》,在页面中会看到有个 服务器配置 如果是停用状态,点击右边 启用 按钮,先启动服务器配置,然后再点击 修改配置 按钮,表单中会有四个选项:

  1. 服务器地址(URL)
  2. 令牌(Token)
  3. 消息加解密密钥(EncodingAESKey)
  4. 消息加解密方式
每个参数是什么意思官方都出了详细解释,可参考最下面官方文档链接查看,下面简单说下这个的基本验证流程。

验证流程

服务器的地址,这必须是一个外网可以访问的URL,当你点击保存按钮的时候,微信会向这个URL发送请求,同时会以get的形式给你携带以下几个参数:

  • signature
  • nonce
  • timestamp
  • echostr

我们需要用noncetimestamp以及上面配置的令牌(Token)通过字典的排序之后再拼接成一个字符串,通过加密解密函数,得出一个结果 签名 ,然后用这个 签名signature 去对比,如果一致,代表是微信服务器请求,则直接返回 echostr ,微信收到此值,代表我们服务器校验通过。

上面这一轮操作实际上是为了验证来自我们接收的消息是不是来自微信服务器。

基本验证

那既然这样的话,我们先撸上代码再说,我的项目是多模块,那么我新建了一个weixin 模块,在此模块中新建控制器publicAuth.js,在indexAction方法中先简单的写上如下代码:

indexAction() {
    // 接收微信服务器传输过来的参数
    const {
      signature,
      nonce,
      timestamp,
      echostr
    } = this.get('signature,nonce,timestamp,echostr');
    if (echostr) {
      this.body = echostr;
    } else {
      return this.json({
        msg: '匿名访问'
      });
    }
  }

上面代码中,暂时没有校验签名,直接先根据参数中是否包含 echostr 来测试下,如果有该参数,直接把此值设为响应内容给微信,否则直接返回错误消息到浏览器。

我们先本地跑一下,访问这个URL,直接访问,不带任何参数,浏览器应该会输出json信息,当加上echostr参数时,会直接在浏览器上输出此值,此刻,代表基本代码可以运行,我们提交到服务器,在线上再测试下,如果OK,那么到微信配置的页面,在服务器地址填上可访问的URLToken暂时随便写,填完之后,点击提交按钮,如果提示提交成功,代表OK。

真实校验

上面只是基本测试,当然不能这么随意,下面贴上最终的校验完整代码。

单模块 src/config/config.环境变量.js or 多模块 src/common/config/config.环境变量.js

module.exports = {
  // ...
  wechat: {
    token: '微信公众平台配置的token,必须保持一致'
  }
};

控制器 publicAuth.js 完整代码如下:

const Base = require('./base.js');
const sha1 = require('sha1');
module.exports = class extends Base {
  indexAction() {
    const {
      signature,
      nonce,
      timestamp,
      echostr
    } = this.get('signature,nonce,timestamp,echostr');
    const token = this.config('wechat').token;
    let str = [token, timestamp, nonce].sort().join('');
    let sha = sha1(str);
    think.logger.info('sha', sha);
    think.logger.info('signature', signature);
    think.logger.info('echostr', echostr);
    if (sha === signature) {
      think.logger.info('sha === signature');
      this.body = echostr;
    } else {
      think.logger.error('sha !== signature');
      return this.json({
        msg: 'sha !== signature',
        token
      });
    }
  }
};

在第二行引入了 sha1 这个包,这是在算签名时需要用到的,最终算出来之后得到的 sha 来和微信给的 signature 对比,一致代表成功,返回 echostr ,否则就是失败。

此代码写好之后,本地就没发测试了,就只能通过微信公众平台来进行真实测试,如果测试成功,那么恭喜你,如果失败,请参考官方文档或自行搜索答案。

注意事项

  • Token 令牌,微信中的配置和代码中必须严格一致,且符合要求
  • 响应给微信echostr时,不能直接return,微信要的是直接纯文本,在网上看到,PHP经常会在这一步出问题,因为输出的内容不纯导致的。

为何不用插件

别人写好的插件是好,但自己写一遍,更能加深自己的理解,然后对于第三方的接入,一般我只喜欢用官方的SDK或他人写的特别优秀,哈哈哈哈。

参考链接

微信接入服务器验证Token官方文档

Last modification:December 1st, 2019 at 01:12 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment