微信小程序登錄態(tài)控制深入分析
微信小程序登錄態(tài)控制深入分析
最近微信小程序終于開(kāi)放了個(gè)人注冊(cè),我當(dāng)然不能浪費(fèi)這個(gè)炫技的好機(jī)會(huì),“菲麥日程”小程序正在全力推進(jìn)中,盡請(qǐng)期待~~
在登錄態(tài)控制中,摸索嘗試了小一陣子,特此分享
一、微信建議的登錄態(tài)控制
說(shuō)明:
1)小程序內(nèi)通過(guò)wx.login接口獲得code
2)將code傳入后臺(tái),后臺(tái)對(duì)微信服務(wù)器發(fā)起一個(gè)https請(qǐng)求換取openid、session_key
3)后臺(tái)生成一個(gè)自身的3rd_session(以此為key值保持openid和session_key),返回給前端。
PS:微信方的openid和session_key并沒(méi)有發(fā)回給前端小程序
4)小程序拿到3rd_session之后保持在本地
5)小程序請(qǐng)求登錄區(qū)內(nèi)接口,通過(guò)wx.checkSession檢查登錄態(tài),如果失效重新走上述登錄流程,否則待上3rd_session到后臺(tái)進(jìn)行登錄驗(yàn)證
二、可不可以不接受它的建議
不是我反骨,而是我的微信小程序不需要獲取什么私密數(shù)據(jù),用不到session_key,只需要一個(gè)openid,微信特別強(qiáng)調(diào)了,為了自身應(yīng)用安全,session_key 不應(yīng)該在網(wǎng)絡(luò)上傳輸,可沒(méi)說(shuō)不可以傳輸openid,那么如果我將openid直接返回給前端小程序,會(huì)不會(huì)方便很多?下面我們來(lái)具體分析下:
永不過(guò)期的openid:
要知道,session_key有過(guò)期時(shí)間,必須適時(shí)重新獲取,而針對(duì)每一個(gè)小程序,唯一標(biāo)識(shí)用戶的openid可不會(huì)過(guò)期,如果只在用戶第一次登錄的時(shí)候,通過(guò)后臺(tái)請(qǐng)求到openid,小程序緩存到本地,之后每次請(qǐng)求都以這個(gè)openid作為唯一憑證,豈不是一本萬(wàn)利~~
事實(shí)上,上面的做法忽略了一個(gè)致命的問(wèn)題,手機(jī)上是可以切換微信賬戶的,如果手機(jī)I上原先登錄了賬戶A,已經(jīng)保存了用戶A的openid,有一天手機(jī)I上切換到了賬戶B上,小程序檢測(cè)到openid存在,并不會(huì)重新獲取openid,那么賬戶B就請(qǐng)求到了賬戶A的數(shù)據(jù),這就造成數(shù)據(jù)亂象了
登錄態(tài)過(guò)期后重新獲取openid:
上述的問(wèn)題并不能打消我使用openid作為登錄憑證的念頭,只需要稍作改進(jìn),數(shù)據(jù)就不會(huì)亂竄:每次進(jìn)入小程序通過(guò)wx.checkSession檢測(cè)登錄是否失效,如果失效重新獲取openid,要知道,手機(jī)切換了登錄賬號(hào),登錄態(tài)一定會(huì)過(guò)期,這樣雖不能一本萬(wàn)利,但也足夠省心。
這個(gè)時(shí)候應(yīng)該有一個(gè)然而,以永不過(guò)期的openid作為登錄憑證,并不是明智之舉,一旦被人截獲,就再也沒(méi)有翻身的機(jī)會(huì)了,而維護(hù)一個(gè)第三發(fā)的session,至少擁有有效期,這在很大程度上增加了安全性。并且,現(xiàn)在不需要使用session_key,不代表以后,保持系統(tǒng)的可擴(kuò)展性,才能以不變應(yīng)萬(wàn)變
事實(shí)證明,我還是應(yīng)該接受它的建議
三、基于redis維護(hù)3rd_session
維護(hù)3rd_session需要一個(gè)內(nèi)存數(shù)據(jù)庫(kù),這里我選用了redis
維護(hù)會(huì)話態(tài)是內(nèi)存數(shù)據(jù)庫(kù)的典型應(yīng)用場(chǎng)景,畢竟量小,并且要求速度快,這么一個(gè)小應(yīng)用,當(dāng)然也可以自己在內(nèi)存中維護(hù)一個(gè)對(duì)象來(lái)進(jìn)行會(huì)話id的處理,但是肯定難以跟一個(gè)成熟的系統(tǒng)相媲美
拋開(kāi)代碼實(shí)現(xiàn),這似乎就是一句話可以概括的事情,生成一個(gè)唯一的隨機(jī)串sessionid,以此為key,openid和微信方的session_key為value存入redis,并把sessionid傳回給客戶端。
但是,翻遍小程序的官方文檔,除了一句據(jù)說(shuō)的wx.checkSession對(duì)開(kāi)發(fā)者來(lái)說(shuō)是透明的,并沒(méi)有小程序登錄態(tài)何時(shí)過(guò)期的具體說(shuō)明,如何才能同步前后端的會(huì)話過(guò)期時(shí)間呢?
四、前后端會(huì)話過(guò)期時(shí)間同步
一開(kāi)始,我還是試圖尋找小程序的登錄態(tài)時(shí)效
{"session_key":"...","expires_in":7200,"openid":"..."}
在code2session接口返回的數(shù)據(jù)中,有一個(gè)可疑的字段expires_in,它的值是7200,似乎存儲(chǔ)到redis中的sessionid設(shè)置為7200就可以同步了??墒菍?shí)踐的結(jié)果再次讓人失望,不管是設(shè)置成7200還是60*60*24(一天),都出現(xiàn)了小程序會(huì)話尚在有效期,而服務(wù)器端會(huì)話已經(jīng)過(guò)期的情況,這直接導(dǎo)致了小程序帶著已經(jīng)緩存的sessionid到服務(wù)器端請(qǐng)求接口,返回未登錄的情況
看來(lái)還是只有wx.checkSession才知道小程序會(huì)話啥時(shí)候過(guò)期,于是,作戰(zhàn)方案重新做了調(diào)整,如果wx.checkSession檢測(cè)到會(huì)話失效,那么帶上已經(jīng)緩存在本地的sessionid(如果有的話),重新發(fā)起登錄請(qǐng)求,后臺(tái)從code2session中拿到新的請(qǐng)求結(jié)果后,生成新的隨機(jī)sessionid并入庫(kù)reids,并且把老的sessionid移除(如果有的話)
當(dāng)然不移除也不會(huì)帶來(lái)什么功能上的影響,但是會(huì)存在兩個(gè)問(wèn)題,首先,跟使用open_id作為登錄憑證一樣,舊的sessionid永不過(guò)期,其次,無(wú)用的session數(shù)據(jù)占用redis資源,會(huì)拖垮訪問(wèn)性能
五、“脫貧致富指數(shù)”統(tǒng)計(jì)
我給小程序的用戶數(shù)安了一個(gè)高大上的名字“脫貧致富指數(shù)”,純屬娛樂(lè),切勿當(dāng)真
為了統(tǒng)計(jì)使用小程序的用戶數(shù),需要一個(gè)表來(lái)保存用戶數(shù)據(jù),后臺(tái)提供一個(gè)接口,讓小程序?qū)⒂脩魯?shù)據(jù)傳上來(lái)進(jìn)行一個(gè)注冊(cè)操作,當(dāng)然可以把這個(gè)功能合并到登錄接口上,每次登錄都把前端小程序獲得的微信用戶數(shù)據(jù)帶上,如果發(fā)現(xiàn)數(shù)據(jù)庫(kù)中還沒(méi)有該用戶的信息,則進(jìn)行入庫(kù)操作
不難發(fā)現(xiàn),其實(shí)只需要用戶第一次登錄的時(shí)候注冊(cè)一次就行了,所以上述方法雖然簡(jiǎn)便,但是有點(diǎn)浪費(fèi)帶寬,所以應(yīng)該額外提供一個(gè)注冊(cè)接口,登錄接口只需要返回一個(gè)用戶是否已經(jīng)注冊(cè)的標(biāo)志,讓客戶端決定是否需要獲取用戶信息,進(jìn)行注冊(cè)操作(當(dāng)然后臺(tái)也不會(huì)讓同一個(gè)用戶重復(fù)入庫(kù))
那么問(wèn)題就變成如何判斷用戶是第一次登錄了:
1)判斷登錄請(qǐng)求中有沒(méi)有帶上sessionid,如果沒(méi)帶上,肯定是第一次登錄;如果帶上了就是登錄過(guò)的用戶?不,別忘了,前面說(shuō)過(guò),用戶可能會(huì)在同一設(shè)備切換賬戶,那就有可能在登錄接口中帶上了別人sessionid,那并不能表明用戶曾經(jīng)登錄過(guò)
2)通過(guò)帶上來(lái)的sessionid從redis中拿到openid,跟在code2session新請(qǐng)求到的openid進(jìn)行比對(duì),如果一致,可以證明用戶曾經(jīng)登錄過(guò),否則,仍需要用戶進(jìn)行注冊(cè)
總結(jié)
時(shí)間是浪費(fèi)了那么一些,但是進(jìn)過(guò)思考摸索,代碼肯定更完備了~~
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- 微信小程序開(kāi)發(fā)一鍵登錄 獲取session_key和openid實(shí)例
- 微信小程序 本地存儲(chǔ)及登錄頁(yè)面處理實(shí)例詳解
- 微信小程序開(kāi)發(fā)(一) 微信登錄流程詳解
- 微信小程序 登錄實(shí)例詳解
- 微信小程序搭建及解決登錄失敗問(wèn)題
- 微信小程序 MD5加密登錄密碼詳解及實(shí)例代碼
- 微信小程序 后臺(tái)登錄(非微信賬號(hào))實(shí)例詳解
- 微信小程序 登錄的簡(jiǎn)單實(shí)現(xiàn)
- 微信小程序?qū)崙?zhàn)之登錄頁(yè)面制作(5)
- 微信小程序中做用戶登錄與登錄態(tài)維護(hù)的實(shí)現(xiàn)詳解
相關(guān)文章
JSON字符串轉(zhuǎn)換JSONObject和JSONArray的方法
這篇文章主要介紹了JSON字符串轉(zhuǎn)換JSONObject和JSONArray的方法的相關(guān)資料,需要的朋友可以參考下2016-06-06
ChatGPT用于OA聊天助手導(dǎo)致訪問(wèn)量服務(wù)宕機(jī)
這篇文章主要為大家介紹了ChatGPT用于OA聊天助手導(dǎo)致訪問(wèn)量服務(wù)宕機(jī),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
JS 4個(gè)超級(jí)實(shí)用的小技巧 提升開(kāi)發(fā)效率
JS有很多小技巧可以使代碼更精簡(jiǎn)、更簡(jiǎn)單。今天主要分享4個(gè)技巧,在平時(shí)的工作中可以大大的縮短代碼量和開(kāi)發(fā)時(shí)間。,需要的朋友可以參考下面文章內(nèi)容喲2021-09-09
JavaScript中document.activeELement焦點(diǎn)元素介紹
這篇文章主要給大家分享 JavaScript中document.activeELement焦點(diǎn)元素介紹,下面文章圍繞了document.activeElement屬性展開(kāi)詳細(xì)內(nèi)容,需要的朋友可以參考一下,希望對(duì)大家有所幫助2021-11-11
微信公眾號(hào) 客服接口的開(kāi)發(fā)實(shí)例詳解
這篇文章主要介紹了微信公眾號(hào) 客服接口的開(kāi)發(fā)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2016-09-09
微信小程序 時(shí)間格式化(util.formatTime(new Date))詳解
這篇文章主要介紹了微信小程序 時(shí)間格式化(util.formatTime(new Date))詳解的相關(guān)資料,這里附實(shí)例,一目了然很容易解決,需要的朋友可以參考下2016-11-11


