nodejs实现获取微信公众号js-sdk开发配置
步骤:
- 获取access_token(有效期7200秒)
- 第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒)
- 生成签名:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。
(1)对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1
(2)对string1进行sha1签名,得到signature
var express = require('express');
var router = express.Router();
var request = require('request')
var sha1 = require('sha1')
const APP_ID = '你的appid'
const APP_SECRET = '你的appsecret'
let nonceStr = ''
let timestamp = ''
/* 前端请求此接口获取config */
router.get('/', function (req, res, next) {
let url = req.headers.referer // 获取url
getToken().then(getTicket).then((ret) => {
res.json({ // 返回前端需要的配置config
appId: APP_ID,
signature: signature(ret, url),
timestamp,
nonceStr
})
})
});
/* 获取token */
function getToken() {
return new Promise((resolve, reject) => {
request.post({
url: 'https://api.weixin.qq.com/cgi-bin/token',
form: {
appid: APP_ID,
secret: APP_SECRET,
grant_type: 'client_credential'
}
}, function (error, response, body) {
if (error) {
console.error(error)
reject(error)
}
body = JSON.parse(body)
resolve(body.access_token)
})
})
}
/* 通过token,获取jsapi_ticket */
function getTicket(accessToken) {
return new Promise((resolve, reject) => {
request.post({
url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
form: {
type: 'jsapi',
access_token: accessToken
}
}, function (error, response, body) {
if (error) {
console.error(error)
reject(error)
}
body = JSON.parse(body)
resolve(body.ticket)
})
})
}
/**
* 签名算法
* @param ticket 用于签名的 jsapi_ticket
* @param url 用于签名的 url ,注意必须动态获取
* @return sha1算法加密的字符串
*/
function signature(ticket, url) {
nonceStr = createNonceStr() // 生成随机字符串
timestamp = createTimestamp() // 获取当前时间戳
var ret = {
jsapi_ticket: ticket,
nonceStr,
timestamp,
url: url
}
var string = raw(ret) // 排序拼接为字符串
return sha1(string) // 返回sha1加密的字符串
}
/* 生成随机字符串 */
function createNonceStr() {
return Math.random().toString(36).substr(2, 15)
}
/* 获取当前时间戳 */
function createTimestamp() {
return parseInt(new Date().getTime() / 1000) + ''
}
/* 排序拼接 */
function raw(args) {
var keys = Object.keys(args) // 获取args对象的键值数组
keys = keys.sort() // 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)
var newArgs = {}
keys.forEach(function (key) { // 所有参数名均为小写字符,按照排序重新生成一个对象
newArgs[key.toLowerCase()] = args[key]
})
var string = ''
for (var k in newArgs) { // 循环新对象,拼接为字符串
string += '&' + k + '=' + newArgs[k]
}
string = string.substr(1) // 截取第一个字符以后的字符串(去掉第一个‘&’)
return string
}
module.exports = router;