const express = require('express')
const app = express()
const crypto = require('crypto') //引入node内置加密模块
const randomstring = require('randomstring') //引入第三方产生随机字符串模块,来产生nonceStr
const axios = require('axios') //请求获取access_token对应的接口(查看文档)
const hash = require('./model/hash.js') //引入封装的hash加密模块
const appId = 'wxff781f2d374c2a1a'
const appSecret ='04dd0125daf8ae53d0448513fe6428e9'
const path=require('path')
const ejs = require('ejs') //引入ejs模板引擎
app.set(path.join(__dirname,'./views'),'views')
app.set('view engine','ejs')
//********************************* token验证 ***************************/
app.get('/token',(req,res)=>{ // http://hmx.nat300.top/token
console.log(req.query)
let token = 'hahaha' // 对应的 token == 'haha'
let {signature,echostr,timestamp,nonce} = req.query // signature = timestamp + nonce + token
let str = [timestamp,nonce,token].sort().join('') //进行字典排序,组成新的字符串
let hash = crypto.createHash('sha1').update(str).digest('hex') //通过内置模块Hash加密,digest('hex')是转换成十六进制
if(hash === signature){ // 按照微信平台加密规则获取的hash === 微信系统产生的signature,则token 一样,验证通过
res.send(echostr) // 验证通过,返回echostr,通知微信平台服务器配置
}else{
res.send('验证失败')
}
})
//********************************* JS-SDK安全域名配置 ***************************/
app.get('/wx/MP_verify_QmSer2vGh4wSH8Q3.txt',(req,res)=>{
res.send('QmSer2vGh4wSH8Q3')
})
//********************************* 配置JS-SDK ***************************/
//appId 公众号的唯一标识,timestamp 生成签名的时间戳,nonceStr 生成签名的随机串,signature签名
app.get('/jssdk',(req,res)=>{
let tmpDate = (new Date()).getTime().toString() //得到毫秒时间戳
let timestamp = tmpDate.substring(0,tmpDate.length-3) //转换以秒为单位的时间戳
let nonceStr = randomstring.generate(16); //第三方模块,randomstring产生随机字符串
let config = {
appId,
timestamp,
nonceStr,
jsapi_ticket: '',
signature: '',
url: 'http://hmx.nat300.top/jssdk' //当前调用jssdk页面的url
}
// console.log(config)
//------ 获取access_token ---------
let access_url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`
axios.get(access_url)
.then((result)=>{
// console.log(result.data)
let access_token = result.data.access_token
//--------- 获取jsapi_ticket --------
let ticket_url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`
return axios.get(ticket_url)
})
.then((result)=>{
// console.log(result.data)
if(result.data.errcode===0){
config.jsapi_ticket = result.data.ticket
//将config对象传过去,进行加密,返回加密后的signature,-------- 获取signature --------
config.signature= hash.createSignatue(config)
console.log(config)
res.render('index',config)
}else{
throw new Error(result.data.errmsg)
}
})
.catch((err)=>{
//出错的话,打印err,查看错误信息
console.log(err)
})
})
app.listen(80,()=>{
console.log('服务器启动')
})
二、signature加密,model文件夹下的hash,js文件
const crypto = require('crypto') //引入node内置加密模块
const hash = {
createSignatue(obj){
// console.log(obj)
let {nonceStr,jsapi_ticket,timestamp,url} = obj
let str = `jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}×tamp=${timestamp}&url=${url}`
//进行hash加密
let signature = crypto.createHash('sha1').update(str).digest('hex')
return signature
}
}
module.exports=hash
三、页面渲染,引入ejs模板,views文件夹下的index.ej文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
</head>
<body>
哈哈
<script>
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '<%= appId%>', // 必填,公众号的唯一标识
timestamp: '<%= timestamp%>', // 必填,生成签名的时间戳
nonceStr: '<%= nonceStr%>', // 必填,生成签名的随机串
signature: '<%= signature%>',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
wx.ready(function(res){
console.log(res)
console.log('配置ok')
});
wx.error(function(res){
// console.log(res)
console.log('配置不正确')
});
</script>
</body>
</html>
这里购买了NATAPP域名并完成配置:http://hmx.nat300.top,开启内网穿透,NATAPP
(购买了NATAPP域名、配置操作链接:https://blog.csdn.net/qq_41287423/article/details/86547044)
打开开发者工具,选择微信公众号项目,输入对应的接口,如以上配置的:http://hmx.nat300.top/jssdk,进行测试