這篇文章主要講解了“小程序開發(fā)怎么實現(xiàn)token統(tǒng)一管理”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“小程序開發(fā)怎么實現(xiàn)token統(tǒng)一管理”吧!
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序定制開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了趙縣免費建站歡迎大家使用!對于使用過公眾平臺的API功能的開發(fā)者來說,access_token絕對不會陌生,它就像一個打開家門的鑰匙,只要拿著它,就能使用公眾平臺絕大部分的API功能。因此,對于開發(fā)者而言,access_token的使用方式就變得尤其的重要。在日常API接口的運營中,經(jīng)常遇到各種的疑問:為什么我的access_token突然非法了?為什么剛剛拿到的access_token,用了10min就過期了?對于這些疑問,我們提供出access_token的設(shè)計方案,便于開發(fā)者對access_token使用方式上的理解。
眾所周知,access_token是通過appid和appsecret來生成的。內(nèi)部設(shè)計的步驟如下:
(1)開發(fā)者通過https請求方式: GET https://API.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,傳入appid及apppsecret的參數(shù)
(2)公眾平臺后臺會校驗appid和哈希(appsecret)是否與存儲匹配,若匹配,結(jié)合當前時間戳,生成新的access_token。
(3)生成新的access_token的同時,會對老的access_token的過期時間戳更新為當前時間戳。
(4)返回新的access_token給開發(fā)者。
這里以圖示的方式說明一下,新舊token交替過程:
從上圖需要注意的幾點:
(1)公眾平臺存儲層只會存儲新老兩個access_token,意味著假設(shè)開發(fā)者重復調(diào)用3次接口,則會導致最早的access_token立刻失效。
(2)雖然請求新的access_token后,老的access_token過期時間會更新為當前時間,但也不會立刻失效,原理請參考 【2.2 access_token 的逐漸失效性】
(3)出于信息安全考慮,公眾平臺并不會明文存儲appsecret,僅存儲appid以及appsecret的哈希值。因此開發(fā)者要妥善保管appsecret。當appsecret疑似泄露時,需要及時登錄mp.weixin.qq.com重置appsecret。
從【access_token的時效性】了解到,當開發(fā)者請求獲取新的access_token時,老的access_token過期時間會被更新為當前時間,但此時不會立刻失效,因為公眾平臺會提供【5分鐘的新老access_token交替緩沖時間】,因此也稱為access_token
的逐漸失效性。
實現(xiàn)的原理是:
由于老的access_token過期時間戳已被刷新,所以在API接口請求期間,帶上的access_token解開后,過期時間戳會加上5分鐘,然后和當前設(shè)備時間進行比對,若超過當前設(shè)備時間,判斷為失效。
公眾平臺的設(shè)備會保持時鐘同步,但設(shè)備之間仍然可能會存在1-2分鐘的時間差異,所以【5分鐘】并非絕對的時間值。當開發(fā)者獲取到新的access_token后應(yīng)該盡快切換到新的access_token。
從上圖需要注意的幾點:
(1)由于存在設(shè)備時間同步的差異,可能會導致開發(fā)者遇到拿著老的access_token請求API接口,部分請求成功,部分請求失敗的情況,建議開發(fā)者獲取到新的access_token后盡快使用。
(2)通過理解兩個圖示,對開發(fā)者來說,access_token是相當關(guān)鍵且不能亂調(diào)的接口,建議開發(fā)者統(tǒng)一管理access_token,以免造成多次請求導致access_token失效。
將access_token
的更新交給定時觸發(fā)器完成所有用到access_token
的接口調(diào)用,不傳入access_token
,交由后端從數(shù)據(jù)庫中讀取
下面以小程序云函數(shù)端統(tǒng)一管理access_token
代碼為例展示
index.js 請求并更新access_token
如果在其他端,需要傳入APPID
const cloud = require("wx-server-sdk") cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const timeutil = require("./timeutil"); // 需要修改的配置項 const APPSECRET = "" const axios = require("axios"); const db = cloud.database(); // 定時刷新獲取配置信息 const CONFIG = "cloud-token"; // 獲取TOKEN const URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}" function getAccessToken(APPID,APPSECRET){ let url = URL; url = url.replace("{APPID}",APPID) url = url.replace("{APPSECRET}",APPSECRET) return new Promise(function(resolve,reject){ axios.get(url).then(function (response) { console.log(response); resolve(response) }) .catch(function (error) { console.log(error); reject(error) }); }) } // 云函數(shù)入口函數(shù) exports.main = async (event, context) => { const wxContext = cloud.getWXContext() // 自動獲取當前應(yīng)用APPID var APPID = wxContext.APPID; return new Promise(function(resolve,reject){ getAccessToken(APPID,APPSECRET).then(async res=>{ console.log(res) let access_token = res.data.access_token; let ans = await db.collection(CONFIG).doc("access_token").set({ data:{ value:access_token, _updateTime:timeutil.TimeCode() } }) resolve(ans) }) }) }
config.json 定時觸發(fā)器
每小時觸發(fā)一次
{ "triggers": [ { "name": "myTrigger", "type": "timer", "config": "0 0 * * * * *" } ] }
timeutil.js 時間工具類
function TimeCode() { var date = new Date(); var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() var hour = date.getHours() var minute = date.getMinutes() var second = date.getSeconds() return [year, month, day].map(formatNumber).join("-") + " " + [hour, minute, second].map(formatNumber).join(":") } //獲取日期 function _formatTime(time) { var date = time.getFullYear() + "年" + time.getMonth() + "月" + time.getDate() + "日" var ftime = time.getHours() + "時" + time.getMinutes() + "分" + time.getSeconds() + "秒" return date + ftime; } function TimeCodeYmd(){ var date = new Date(); var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() return [year, month, day].map(formatNumber).join("-"); } function formatNumber(n) { n = n.toString() return n[1] ? n : "0" + n } module.exports={ TimeCode, TimeCodeYmd }
其他云函數(shù)中使用到access_token
的地方,通過查詢數(shù)據(jù)庫進行獲取,二者通過數(shù)據(jù)庫進行邏輯耦合。
access_token 查詢使用
const TOKEN = "cloud-token"; //獲取access_token try { let tres = await db.collection(TOKEN).doc("access_token").get(); access_token = tres.data.value; console.log(access_token) } catch (error) { console.log("--無token記錄--") return { errCode:-1, errMsg:"數(shù)據(jù)庫中無TOKEN信息" } }
感謝各位的閱讀,以上就是“小程序開發(fā)怎么實現(xiàn)token統(tǒng)一管理”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對小程序開發(fā)怎么實現(xiàn)token統(tǒng)一管理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!