本文介绍使用 Node.js 进行微信公众号接入的完整流程。内容涵盖内网穿透工具的选择与配置、LeanCloud 云引擎的部署命令及环境设置,以及基于 SHA1 加密和字典序排序的服务器地址有效性验证代码实现。
Node.js 微信开发概述与工具选择
近期重新开展微信公众账号开发工作。此前的公众号后端基于 Flask 构建,现计划将其迁移至 Node.js 环境。本文旨在记录开发过程,结合代码编写同步整理相关文档。
作者对 Node.js 的使用尚处于初级阶段,文中若存在技术错误或表述不当之处,欢迎指正。
文章末尾将提供完整源码链接。公众号服务部署于 LeanCloud 平台,此处将简要介绍 LeanCloud 云引擎的使用方法,以协助读者完成部署。
本文涉及的代码量较少,主要侧重于工具介绍及微信接入流程的说明。
内网穿透配置
微信开发要求服务器端口必须为 80(近期支持 443 端口),因此使用内网穿透工具至关重要。个人推荐使用 QQ 浏览器微信调试工具。
鉴于同属一家,该工具是推荐选项。此外还有其他替代方案:
花生壳 该工具速度表现尚可,但仅提供 Windows 客户端。虽然理论上可配置路由器相关设置,但未深入测试。
nat123 功能与花生壳类似,但运行速度较慢且常出现配置错误。尽管号称免费,却需预充值少量金额,因此不推荐。
ngrok 这是一款开源软件,支持在自有服务器部署或使用现成服务。QQ 浏览器微信调试工具即基于 ngrok 构建,整体使用体验较好。
LeanCloud 云引擎部署指南
LeanCloud 平台介绍
选择 LeanCloud 主要因缺乏其他云服务的使用经验,无法进行横向对比。另一选项 Heroku 在国内访问速度较慢。LeanCloud 提供类似 Parse 的服务,并支持托管 Web 应用的云引擎,包括 Python 和 Node.js 两种环境,此处重点介绍 Node.js 引擎。详细入门指南请参考官方文档,其内容比本文更为详尽。对于个人开发者,LeanCloud 目前免费且限制较少,尽管近期引入实名认证要求,但未认证似乎不影响基本使用。需注意,若应用无请求访问,服务会进入睡眠状态,导致无法打开,此时重试几次即可唤醒。
常用命令行工具
lean new新建项目
lean app add [appname] [appid] 关联项目到 LeanCloud 云引擎
lean up 启动本地服务
lean deploy部署应用(付费用户通常部署至测试环境)
lean publish部署到开发环境(免费用户通常无需此步骤)
云引擎配置简介
进入控制台后界面如下:

存储模块用于数据库管理,各功能模块名称直观。部分暂不使用的功能在此略过。
重点在于云引擎选项,需进入设置界面配置域名。

数据库配置
LeanCloud 的数据库基于 MongoDB 简化而成,基本功能已足够使用。相关文档可参考 JS 数据开发指南。
微信公众号服务器接入验证
微信公众号接入流程
此处使用公众号测试号,因个人申请的订阅号功能受限较多。
首先参考微信官方文档。

填写服务器配置信息

即上图所示的接口配置信息。URL 指向服务部署地址,图中 URL 由微信调试工具生成,因此显示较为复杂。Token 可随意填写,但需妥善保存,后续验证将用到。
验证服务器地址有效性
此处涉及代码实现。先展示项目目录结构:

app目录存放业务逻辑代码。
config.js 文件存储相关配置,包括微信公众号的 appId 和 Token 等。
module.exports = {
'token': 'yourtoken',//配置中的token
'appId': 'your appid',//配置里的appid
'appSecret': 'your appsecret'//配置中的appsecret
};
注:以下内容引用自微信公众平台官方文档。
开发者提交信息后,微信服务器将向填写的服务器地址 URL 发送 GET 请求,请求携带参数如下表所示:

通过检验 signature 对请求进行校验(校验方式见下文)。若确认 GET 请求来自微信服务器,请原样返回 echostr 参数内容,则接入生效,开发者认证成功,否则接入失败。加密/校验流程如下: 1)将 token、timestamp、nonce 三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行 sha1 加密 3)开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信
相关代码实现如下:
const crypto = require('crypto');
const path = require('path');
const url = require('url');
//import config
const config = require('../../config');
//进行sha1加密
function sha1(str) {
var shasum = crypto.createHash("sha1");
shasum.update(str);
str = shasum.digest("hex");
return str;
}
function wechatAuth(req, res) {
var query = url.parse(req.url, true).query;
var signature = query.signature;
var echostr = query.echostr;
var timestamp = query['timestamp'];
var nonce = query.nonce;
var reqArray = [nonce, timestamp, config.token];
//对数组进行字典排序
reqArray.sort();
var sortStr = reqArray.join('');//连接数组
var sha1Str = sha1(sortStr);
if (signature === sha1Str) {
res.end(echostr);
} else {
res.end("false");
console.log("授权失败!");
}
}
module.exports = wechatAuth;
代码逻辑清晰:首先获取请求 URL 中的四个参数,对 nonce、timestamp 和 token 进行字典排序,即调用 Array.sort(),随后拼接字符串并进行 SHA1 加密。若计算结果与 signature 相等,则验证成功(注:直接返回 echostr 也可通过验证,但后续请求处理可能受阻)。
至此,接入流程应已顺利完成。
GitHub 源码地址:https://github.com/xiadd/shorthand
以上为本文全部内容,希望对读者学习有所帮助,欢迎支持本站。