创作者 » 陈帅华
版权声明 » 自由转载-保持署名-非商用-非衍生
发布日期 » 2017年9月6日 周三

验证请求来自微信服务器

全篇共 1100 字。按500字/分钟阅读,预计用时 2.2 分钟。总访问 688 次,日访问 4 次。

基于安全考虑,获取全部微信服务器IP,以过滤并非来自微信服务器的请求。尤其是在用户向公众号发送消息时,微信服务器将消息转发给开发者的服务器,开发者应该在此时检测请求的IP是否为微信服务器。

获取可信赖IP列表

微信公众号为开发者提供了可获取全部微信服务器IP地址的接口,下面是我用Node+Express实现调用接口获取IP地址的代码,我将它封装到一个工具函数中,以备重复使用。函数的返回值是一个Promise实例,结果要么是 true,要么是 false。

// 唯一参数:待检测的IP地址
const isWechatServer = ip => {
  return new Promise(async (resolve, reject) => {
    ip = ip.split('::ffff:')[1];
    try {
      // 用access_token换取微信服务器IP列表
      const accessToken = await getAccessToken();
      const callbackip = await util.getRequest(`https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=${accessToken}`);
      const allWechatServerIp = callbackip['ip_list'];
      var isWechatServer = false;
      for (var i = 0, l = allWechatServerIp.length; i < l; i++) {
        if (allWechatServerIp[i] == ip) {
          isWechatServer = true;
          break;
        }
      }
      isWechatServer ? resolve(true) : resolve(false);
    } catch (e) {
      reject(e);
    }
  });
}

过滤IP

使用Express的中间件,过滤并非来自微信服务器的请求。我接受微信公众号消息的地址是:https://www.shuaihuajun.com/wechat_ol/,只有来自微信服务器的请求才会从这个中间件进入到下一个处理信息的中间件,非微信服务器的IP请求该地址后就会收到404的HTTP响应码。

router.use(async (req, res, next) => {
  if (!await isWechatServer(req.ip)) {
    res.sendStatus(404);
    return;
  }
  next();
});

扩展阅读:

:)记录下你此刻的想法~
来自笔友的留言
JavaScript核心
微信公众平台开发
翻译计划
Node.js实战
数据可视化
UI与动画
网站运维
生活趣味
帅华君的书单
效率脚手架
CSS样式经验之谈
硬件编程