小編給大家分享一下如何實(shí)現(xiàn)基于Node.js的微信JS-SDK后端接口,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供寧江網(wǎng)站建設(shè)、寧江做網(wǎng)站、寧江網(wǎng)站設(shè)計(jì)、寧江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、寧江企業(yè)網(wǎng)站模板建站服務(wù),十多年寧江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。做了一個(gè)網(wǎng)站,放到線上,用微信打開,點(diǎn)擊分享,可是分享后發(fā)給朋友的鏈接卡片是微信默認(rèn)自帶的,如下:
這標(biāo)題,描述以及圖片是默認(rèn)自帶的,丑不說,分享給別人還以為是盜號(hào)網(wǎng)站呢,而接入微信的JSSDK后,分享可以自定義內(nèi)容,如下:
我承認(rèn),雖然這分享的標(biāo)題和內(nèi)容也并不正經(jīng),但這不妨礙我表達(dá)我們可以通過微信JSSDK定義分享內(nèi)容,接下來我們將一步一步從零實(shí)現(xiàn)JSSDK從后端Node.js的接入。
成為測(cè)試公眾號(hào)開發(fā)者
登錄測(cè)試公眾號(hào)后臺(tái)
首先我們需要在微信公眾平臺(tái)申請(qǐng)測(cè)試接口,地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
使用微信掃描登錄后,即可來微信公眾平臺(tái)測(cè)試賬號(hào)系統(tǒng)。
成為測(cè)試公眾號(hào)開發(fā)者
其次在微信公眾平臺(tái)測(cè)試賬號(hào)中,掃描測(cè)試號(hào)二維碼,成為測(cè)試公眾號(hào)的開發(fā)者
接口配置信息
修改接口配置信息
1.URL地址必須是你服務(wù)器上的地址,此地址要能通過瀏覽器的地址欄訪問到(沒有服務(wù)器?沒關(guān)系,一會(huì)兒我們搭建一個(gè))
假設(shè)我這里填寫的服務(wù)器地址是"http://www.your_server_name.com/wxJssdk"
2.Token你可以隨意填寫,用作生成簽名,(不知道簽名?沒關(guān)系,一會(huì)兒會(huì)用到這東西的)
假設(shè)我這里填寫的Token是"jegfjaeghfuccawegfgjdbh"
此時(shí)點(diǎn)擊提交是會(huì)提示配置失敗的,因?yàn)樵谔峤坏臅r(shí)候,微信是會(huì)請(qǐng)求你的服務(wù)器地址,而你的當(dāng)前配置的地址并不能訪問,所以會(huì)提示配置失敗。不過別急,我們先來搭建一個(gè)簡單的Node服務(wù)器,讓微信能夠訪問該服務(wù)器。
搭建簡單的Node服務(wù)器
我們需要在http://www.your_server_name.com 這個(gè)域名上搭建一個(gè)服務(wù)器,并且曝出一個(gè)接口為/wxJssdk
const express = require('express') const app = express() app.get('/wxJssdk', (req, res) => { res.send('請(qǐng)求成功了了了了') }) app.listen(80, err => { if(!err) console.log('connect succeed') })
現(xiàn)在我們?cè)诘刂窓谥性L問http://www.your_server_name.com/wxJssdk ,如果頁面顯示“請(qǐng)求成功了了了了”,則進(jìn)入到下一步,如果沒有成功的話,檢查一下你的服務(wù)器是否開啟Node服務(wù)器,如:node index.js
此時(shí)保存微信測(cè)試公眾號(hào)后臺(tái)的接口配置信息,仍然會(huì)提示配置失敗,這是因?yàn)槲覀儧]有按照它的要求返回。
根據(jù)微信測(cè)試公眾號(hào)請(qǐng)求信息返回對(duì)應(yīng)內(nèi)容
根據(jù)微信公眾號(hào)開發(fā)文檔接入指南,微信在請(qǐng)求我們配置的接口時(shí),會(huì)帶上如下信息
參數(shù) | 描述 |
---|---|
signature | 微信加密簽名,signature結(jié)合了開發(fā)者填寫的token參數(shù)和請(qǐng)求中的timestamp參數(shù)、nonce參數(shù)。 |
timestamp | 時(shí)間戳 |
nonce | 隨機(jī)數(shù) |
echostr | 隨機(jī)字符串 |
微信服務(wù)器會(huì)通過GET請(qǐng)求,來請(qǐng)求我們所配置的接口,并帶上以上表格的信息,而我們必須按照以下要求,將微信發(fā)送的信息進(jìn)行要求校驗(yàn),以確保是微信發(fā)送的信息,其中校驗(yàn)流程如下:
1)將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序
2)將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密
3)開發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來源于微信
const express = require('express') const app = express() const sha1 = require('sha1') app.get('/wxJssdk', (req, res) => { let wx = req.query let token = 'jegfjaeghfuccawegfgjdbh' let timestamp = wx.timestamp let nonce = wx.nonce // 1)將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序 let list = [token, timestamp, nonce].sort() // 2)將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密 let str = list.join('') let result = sha1(str) // 3)開發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來源于微信 if (result === wx.signature) { res.send(wx.echostr) // 返回微信傳來的echostr,表示校驗(yàn)成功,此處不能返回其它 } else { res.send(false) } })
此時(shí)我們重啟Node服務(wù)器,再次保存接口配置信息即可配置成功。
微信JSSDK使用步驟
根據(jù)微信JSSDK說明文檔,我們需要完成如下:
填寫安全域名
登錄微信公眾平臺(tái)進(jìn)入“公眾號(hào)設(shè)置”的“功能設(shè)置”里填寫“JS接口安全域名”,即要調(diào)用接口的域名,不包含協(xié)議
前端引入JS
在需要調(diào)用JS接口的頁面引入此JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
填寫接口的配置信息
wx.config({ debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。 appId: '', // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: , // 必填,生成簽名的時(shí)間戳 nonceStr: '', // 必填,生成簽名的隨機(jī)串 signature: '',// 必填,簽名 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 });
調(diào)用接口
做你前端該做的,調(diào)用微信分享接口,或微信提供的其它接口,whatever you need,當(dāng)然,這并不是我們所要講的重點(diǎn),我們接下來要看一下微信的配置信息從哪獲取
在Node服務(wù)器中生成jssdk所需要的配置信息
從上一節(jié)可以看到,調(diào)用微信JSSDK需要以下信息
1.appId
2.timestamp
3.nonceStr
4.signature
5.jsApiList
其中:
1.第1項(xiàng)appId是測(cè)試公眾號(hào)后臺(tái)的appId,我們已知
2.第2項(xiàng)時(shí)間戳我們也可以自己生成
3.第3項(xiàng)nonceStr可以隨意填寫,你可以理解為密鑰
4.第4項(xiàng)signature則需要我們按要求生成
5.第5項(xiàng)是所需要接口的接口名
生成signature
生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù)。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由于獲取jsapi_ticket的api調(diào)用次數(shù)非常有限,頻繁刷新jsapi_ticket會(huì)導(dǎo)致api調(diào)用受限,影響自身業(yè)務(wù),開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket 。
為了保證我們appid,appsecret,nonceStr等信息不在前端曝露,我們以下步驟將在服務(wù)器上進(jìn)行操作,以免他人盜用信息獲?。ㄗⅲ何⑿耪?qǐng)求有每日次數(shù)限制,一旦超出,則無法使用,具體請(qǐng)求次數(shù)限制在微信公眾號(hào)后臺(tái)中可查看)
生成access_token
根據(jù)微信開發(fā)文檔[獲取access_token文檔說明],我們需要將微信測(cè)試公眾號(hào)后臺(tái)的appid和和appsecret以GET的請(qǐng)求方式向https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET 發(fā)起請(qǐng)求獲取token,請(qǐng)求成功后我們會(huì)獲得下返回JSON轉(zhuǎn)化的字符串
{"access_token":"ACCESS_TOKEN","expires_in":7200}
具體請(qǐng)求代碼如下:
const request = require('request') const grant_type = 'client_credential' const appid = 'your app id' const secret = 'your app secret' request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { let access_toekn = JSON.parse(body).access_token })
獲取jsapi_ticket
const request = require('request') const grant_type = 'client_credential' const appid = 'your app id' const secret = 'your app secret' request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { let access_toekn = JSON.parse(body).access_token request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', (err, response, body) => { let jsapi_ticket = JSON.parse(body).ticket }) })
生成簽名
生成簽名的步驟和最開始的/wxJssdk
的算法是一致的,具體如下:
let jsapi_ticket = jsapi_ticket // 上一步從獲取的jsapi_ticket let nonce_str = '123456' // 密鑰,字符串任意,可以隨機(jī)生成 let timestamp = new Date().getTime() // 時(shí)間戳 let url = req.query.url // 使用接口的url鏈接,不包含#后的內(nèi)容 // 將請(qǐng)求以上字符串,先按字典排序,再以'&'拼接,如下:其中j > n > t > u,此處直接手動(dòng)排序 let str = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + nonce_str + '×tamp=' + timestamp + '&url=' + url // 用sha1加密 let signature = sha1(str)
連接后的代碼為:
const request = require('request') const grant_type = 'client_credential' const appid = 'your app id' const secret = 'your app secret' request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { let access_toekn = JSON.parse(body).access_token request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', (err, response, body) => { let jsapi_ticket = JSON.parse(body).ticket let nonce_str = '123456' // 密鑰,字符串任意,可以隨機(jī)生成 let timestamp = new Date().getTime() // 時(shí)間戳 let url = req.query.url // 使用接口的url鏈接,不包含#后的內(nèi)容 // 將請(qǐng)求以上字符串,先按字典排序,再以'&'拼接,如下:其中j > n > t > u,此處直接手動(dòng)排序 let str = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + nonce_str + '×tamp=' + timestamp + '&url=' + url // 用sha1加密 let signature = sha1(str) }) })
曝露接口,返回給前端
app.post('/wxJssdk/getJssdk', (req, res) => { const request = require('request') const grant_type = 'client_credential' const appid = 'your app id' const secret = 'your app secret' request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { let access_toekn = JSON.parse(body).access_token request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', (err, response, body) => { let jsapi_ticket = JSON.parse(body).ticket let nonce_str = '123456' // 密鑰,字符串任意,可以隨機(jī)生成 let timestamp = new Date().getTime() // 時(shí)間戳 let url = req.query.url // 使用接口的url鏈接,不包含#后的內(nèi)容 // 將請(qǐng)求以上字符串,先按字典排序,再以'&'拼接,如下:其中j > n > t > u,此處直接手動(dòng)排序 let str = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + nonce_str + '×tamp=' + timestamp + '&url=' + url // 用sha1加密 let signature = sha1(str) res.send({ appId: appid, timestamp: timpstamp, nonceStr: nonce_str, signature: signature, }) }) }) })
前端請(qǐng)求后端接口,獲取配置信息
獲取配置
axios.post('/wxJssdk/getJssdk', {url: location.href}).then((response) => { var data = response.data wx.config({ debug: false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。 appId: data.appId, // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: data.timestamp, // 必填,生成簽名的時(shí)間戳 nonceStr: data.nonceStr, // 必填,生成簽名的隨機(jī)串 signature: data.signature,// 必填,簽名,見附錄1 jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 }); })
做你想做的,比如,自定義分享
if (wx) { axios.post('/wxJssdk/getJssdk', {url: location.href}).then((response) => { var data = response.data wx.config({ debug: false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。 appId: data.appId, // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: data.timestamp, // 必填,生成簽名的時(shí)間戳 nonceStr: data.nonceStr, // 必填,生成簽名的隨機(jī)串 signature: data.signature,// 必填,簽名,見附錄1 jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 }); wx.ready(function () { wx.onMenuShareTimeline({ title: wxShare.title, desc: wxShare.desc, link: wxShare.link, imgUrl: wxShare.imgUrl }); wx.onMenuShareAppMessage({ title: wxShare.title, desc: wxShare.desc, link: wxShare.link, imgUrl: wxShare.imgUrl }); }) wx.error(function (res) { // config信息驗(yàn)證失敗會(huì)執(zhí)行error函數(shù),如簽名過期導(dǎo)致驗(yàn)證失敗,具體錯(cuò)誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對(duì)于SPA可以在這里更新簽名。 }) }) }
至此,后端配置好了,我們已經(jīng)能夠正常使用微信的接口了,但是微信每日接口請(qǐng)求是有上限的,通過2000次/天,因此如果網(wǎng)站上線后,一量當(dāng)天訪問量超過2000次你的接口將失效,而且每次都請(qǐng)求微信接口兩次,造成請(qǐng)求時(shí)間浪費(fèi),所以我們需要將以上獲取信息緩存在后端,避免造成接口失效以及多次請(qǐng)求微信后臺(tái)。
緩存access_token及jsapi_ticket
此處直接上代碼,利用node_cache包進(jìn)行緩存
const request = require('request') const express = require('express') const app = express() const sha1 = require('sha1') const waterfall = require('async/waterfall') const NodeCache = require('node-cache') const cache = new NodeCache({stdTTL: 3600, checkperiod: 3600}) //3600秒后過過期 app.get('/wxJssdk', (req, res) => { let wx = req.query // 1)將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序 let token = 'jegfjaeghfuyawegfgjdbh' let timestamp = wx.timestamp let nonce = wx.nonce // 2)將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密 let list = [token, timestamp, nonce] let result = sha1(list.sort().join('')) // 3)開發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來源于微信 if (result === wx.signature) { res.send(wx.echostr) } else { res.send(false) } }) app.get('/wxJssdk/getJssdk', (req, res) => { let grant_type = 'client_credential' let appid = 'your app id' let secret = 'your app secret' // appscret let steps = [] // 第一步,獲取access_token steps.push((cb) => { let steps1 = [] // 第1.1步,從緩存中讀取access_token steps1.push((cb1) => { let access_token = cache.get('access_token', (err, access_token) => { cb1(err, access_token) }) }) // 第1.2步,緩存中有access_token則直接返回,如果沒有,則從服務(wù)器中讀取access_token steps1.push((access_token, cb1) => { if (access_token) { cb1(null, access_token, 'from_cache') } else { request('https://api.weixin.qq.com/cgi-bin/token?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret, (err, response, body) => { cb1(err, JSON.parse(body).access_token, 'from_server') }) } }) // 第1.3步,如果是新從服務(wù)器取的access_token,則緩存起來,否則直接返回 steps1.push((access_token, from_where, cb1) => { if (from_where === 'from_cache') { console.log(' === 成功從緩存中讀取access_token: ' + access_token + ' ===') cb1(null, access_token) } else if (from_where === 'from_server') { cache.set('access_token', access_token, (err, success) => { if (!err && success) { console.log(' === 緩存已過期,從服務(wù)器中讀取access_token: ' + access_token + ' ===') cb1(null, access_token) } else { cb1(err || 'cache設(shè)置access_token時(shí),出現(xiàn)未知錯(cuò)誤') } }) } else { cb1('1.3獲取from_where時(shí),from_where值為空') } }) waterfall(steps1, (err, access_token) => { cb(err, access_token) }) }) // 第二步,獲取ticket steps.push((access_token, cb) => { let steps1 = [] // 第2.1步,從緩存中讀取ticket steps1.push((cb1) => { let ticket = cache.get('ticket', (err, ticket) => { cb1(err, ticket) }) }) // 第2.2步,緩存中有ticket則直接返回,如果沒有,則從服務(wù)器中讀取ticket steps1.push((ticket, cb1) => { if (ticket) { cb1(null, ticket, 'from_cache') } else { request('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_token + '&type=jsapi', (err, response, body) => { cb1(err, JSON.parse(body).ticket, 'from_server') }) } }) // 第2.3步,如果新從服務(wù)器取的ticket,則緩存起來,否則直接返回 steps1.push((ticket, from_where, cb1) => { if (from_where === 'from_cache') { console.log(' === 成功從緩存中讀取ticket: ' + ticket + ' ===') cb1(null, ticket) } else if (from_where === 'from_server') { cache.set('ticket', ticket, (err, success) => { if (!err && success) { console.log(' === 緩存已過期,從服務(wù)器中讀取ticket: ' + ticket + ' ==='); cb1(null, ticket) } else { cb1(err || 'cache設(shè)置ticket時(shí),出現(xiàn)未知錯(cuò)誤') } }) } else { cb1('2.3獲取from_where時(shí),from_where值為空') } }) waterfall(steps1, (err, ticket) => { cb(err, ticket) }) }) // 第三步,生成簽名 steps.push((ticket, cb) => { let jsapi_ticket = ticket let nonce_str = '123456' let timestamp = new Date().getTime() let url = req.query.url let str = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + nonce_str + '×tamp=' + timestamp + '&url=' + url let signature = sha1(str) cb(null, { appId: appid, timestamp: timestamp, nonceStr: nonce_str, signature: signature, ticket: ticket }) }) waterfall(steps, (err, data) => { if (err) { res.send({status: 'error', data: err}) } else { res.send({status: 'success', data: data}) } }) }) app.use('/wxJssdk/public', express.static('public')) app.listen(80, err => { if(!err) console.log('connect succeed') })
以上是“如何實(shí)現(xiàn)基于Node.js的微信JS-SDK后端接口”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站jinyejixie.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
名稱欄目:如何實(shí)現(xiàn)基于Node.js的微信JS-SDK后端接口-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://jinyejixie.com/article42/deopec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、做網(wǎng)站、搜索引擎優(yōu)化、域名注冊(cè)、營銷型網(wǎng)站建設(shè)、用戶體驗(yàn)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容