一、server.js文件
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/tokenconsole.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} = objlet 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,进行测试