這篇文章主要講解了“小程序開發怎么實現token統一管理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“小程序開發怎么實現token統一管理”吧!
TOKEN 定時刷新器
一、背景
對于使用過公眾平臺的API功能的開發者來說,access_token絕對不會陌生,它就像一個打開家門的鑰匙,只要拿著它,就能使用公眾平臺絕大部分的API功能。愛掏網 - it200.com因此,對于開發者而言,access_token的使用方式就變得尤其的重要。愛掏網 - it200.com在日常API接口的運營中,經常遇到各種的疑問:為什么我的access_token突然非法了?為什么剛剛拿到的access_token,用了10min就過期了?對于這些疑問,我們提供出access_token的設計方案,便于開發者對access_token使用方式上的理解。愛掏網 - it200.com
二、access_token的內部設計
2.1 access_token的時效性
眾所周知,access_token是通過appid和appsecret來生成的。愛掏網 - it200.com內部設計的步驟如下:
(1)開發者通過https請求方式: GET https://API.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,傳入appid及apppsecret的參數
(2)公眾平臺后臺會校驗appid和哈希(appsecret)是否與存儲匹配,若匹配,結合當前時間戳,生成新的access_token。愛掏網 - it200.com
(3)生成新的access_token的同時,會對老的access_token的過期時間戳更新為當前時間戳。愛掏網 - it200.com
(4)返回新的access_token給開發者。愛掏網 - it200.com
這里以圖示的方式說明一下,新舊token交替過程:
從上圖需要注意的幾點:
(1)公眾平臺存儲層只會存儲新老兩個access_token,意味著假設開發者重復調用3次接口,則會導致最早的access_token立刻失效。愛掏網 - it200.com
(2)雖然請求新的access_token后,老的access_token過期時間會更新為當前時間,但也不會立刻失效,原理請參考 【2.2 access_token 的逐漸失效性】
(3)出于信息安全考慮,公眾平臺并不會明文存儲appsecret,僅存儲appid以及appsecret的哈希值。愛掏網 - it200.com因此開發者要妥善保管appsecret。愛掏網 - it200.com當appsecret疑似泄露時,需要及時登錄mp.weixin.qq.com重置appsecret。愛掏網 - it200.com
2.2 access_token 的逐漸失效性
從【access_token的時效性】了解到,當開發者請求獲取新的access_token時,老的access_token過期時間會被更新為當前時間,但此時不會立刻失效,因為公眾平臺會提供【5分鐘的新老access_token交替緩沖時間】,因此也稱為access_token
的逐漸失效性。愛掏網 - it200.com
實現的原理是:
由于老的access_token過期時間戳已被刷新,所以在API接口請求期間,帶上的access_token解開后,過期時間戳會加上5分鐘,然后和當前設備時間進行比對,若超過當前設備時間,判斷為失效。愛掏網 - it200.com
公眾平臺的設備會保持時鐘同步,但設備之間仍然可能會存在1-2分鐘的時間差異,所以【5分鐘】并非絕對的時間值。愛掏網 - it200.com當開發者獲取到新的access_token后應該盡快切換到新的access_token。愛掏網 - it200.com
從上圖需要注意的幾點:
(1)由于存在設備時間同步的差異,可能會導致開發者遇到拿著老的access_token請求API接口,部分請求成功,部分請求失敗的情況,建議開發者獲取到新的access_token后盡快使用。愛掏網 - it200.com
(2)通過理解兩個圖示,對開發者來說,access_token是相當關鍵且不能亂調的接口,建議開發者統一管理access_token,以免造成多次請求導致access_token失效。愛掏網 - it200.com
三、access_token的統一管理
將access_token
的更新交給定時觸發器完成所有用到access_token
的接口調用,不傳入access_token
,交由后端從數據庫中讀取
下面以小程序云函數端統一管理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) ????}); ??}) } //?云函數入口函數 exports.main?=?async?(event,?context)?=>?{ ??const?wxContext?=?cloud.getWXContext() ??//?自動獲取當前應用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 定時觸發器
每小時觸發一次
{ ??"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 }
其他云函數中使用到access_token
的地方,通過查詢數據庫進行獲取,二者通過數據庫進行邏輯耦合。愛掏網 - it200.com
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:"數據庫中無TOKEN信息" ????} ??}
感謝各位的閱讀,以上就是“小程序開發怎么實現token統一管理”的內容了,經過本文的學習后,相信大家對小程序開發怎么實現token統一管理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。愛掏網 - it200.com這里是編程筆記,小編將為大家推送更多相關知識點的文章,歡迎關注!