以下为主要实现的关键代码
wechatVerify.js
const { createHash } = require("crypto")
/**
*
* @param {string} algorithm 算法
* @param {string} content 输入内容
* @param {string} outputEncoding 输出编码,默认hex;支持'base64' | 'base64url' | 'hex' | 'binary'
* @returns
*/
const encrypt = (algorithm, content, outputEncoding = 'hex') => {
const hash = createHash(algorithm)
const inputEncoding = 'utf8' // 输入编码:'utf8' | 'utf-8' | 'utf16le' | 'latin1' | 'base64' | 'base64url' | 'hex' | 'binary' | 'ascii' | 'ucs2' | 'ucs-2'
hash.update(content, inputEncoding)
return hash.digest(outputEncoding)
}
/**
* 签名验证
* @param {*}} data 需要签名验证的对象,是一个Object
* @returns
*/
function verify(data) {
const { signature } = data
if (!signature) {
throw new Error()
}
const keys = Object.keys(data).filter(key => key !== "signature").map(key => {
return `${data[key]}`
}).sort()
const tempStr = keys.join("")
const encryptStr = encrypt('sha1', tempStr)
return encryptStr === signature
}
// 提供Api接口:index.js
router.js
// 以下是路由的关键代码, 文件名:router.js
const Router = require('restify-router').Router
const verify = require('./wechatVerify')
const router = new Router()
const token = "token_test" // 此处的token与微信公众号服务器配置的TOKEN一致
async function respond (req, res, next) {
// console.log(req.params, req.query, req.body)
const { signature, timestamp, nonce, echostr } = req.query
if (!signature) {
res.send(201, new MError(1, '参数错误'))
return next()
} else {
if (verify({ token, signature, timestamp, nonce })) {
res.header('Content-Type', 'text/plain;charset=UTF-8')
// console.log(res);
res.send(200, +echostr)
} else {
res.send(200, 0)
}
}
return next()
}
router.get('/verify', (req, res, next) => {
try {
respond(req, res, next)
} catch (error) {
res.json(error)
}
})
module.exports = router
index.js
const restify = require('restify')
const corsMiddleware = require('restify-cors-middleware2')
const publicRouter = require('./router')
const server = restify.createServer({
name: "api",
version: "1.0.0"
})
const cors = corsMiddleware({
preflightMaxAge: 5, // Optional
origins: ['*']
// allowHeaders: ['API-Token'],
// exposeHeaders: ['API-Token-Expiry']
})
server.pre(cors.preflight)
server.use(cors.actual)
server.use(restify.plugins.acceptParser(server.acceptable))
server.use(restify.plugins.queryParser())
server.use(restify.plugins.bodyParser())
publicRouter.applyRoutes(server, '/public')
server.listen(9009, function () {
console.log('%s listening at %s', server.name, server.url)
})
- node index.js 启动服务
- 配置域名,确保微信服务器能访问该域名
- 安装nginx,开放80,443端口,配置nginx,反向代理上面服务的"/public/verify"
- 配置微信服务器上的相关数据,保存时,能成功即可。
微信服务器配置,主要配置URL与TOKEN(与router.js的token一致),消息加解密方式采用明文模式