登陸,幾乎什麼項目都會用到,其重要性不言而喻,而小程序的登陸卻一直是爲人頭疼的一件事,這裏我分享下咱們在小程序登陸上的探索
一般的登陸都是經過一個表單,這很正常,但若是在小程序裏你也這麼作那就有點難以想象了,微信的一鍵登陸對用戶體驗有多好你難道不知道?不用是否是腦子有坑?最主要——你要利用微信的生態必須須要用微信的登陸,以獲取相關信息來和微信交互,OK,咱們進入正題前端
友情提示一下:wx.login
並不須要點擊組件,須要的是wx.getUserInfo
,但一般咱們都會用到UnionID、encryptedData、iv等信息
完成完整的登陸流程,本文主要聚焦的也是這種場景
因此以前直接經過調用API的方式就行不通了,那麼問題來了——這個點擊按鈕要放到哪裏?小程序
在須要受權的時候跳到登錄頁面。這樣就解決了上面遇到的不須要受權的時候也被強制受權,但是這樣好嗎?segmentfault
那就直接放在須要登陸的頁面上(這不是漏斗嗎?不少讀者必定這麼想。但想一想看上面那個場景,點評論時只是須要點擊下彈出的登陸按鈕,並且還假模假樣的以微信的口吻提醒你須要登陸,那你會不會登陸?最起碼你很願意登陸,並且來的很忽然,我控幾不住本身的手就點了!點了!) 後端
但是這種方式有一個問題微信小程序
應該不少人都能想到:抽離出組件,那怎麼保證在須要的頁面都有這個組件呢?錯殺一千也不能放過一個!把登陸組件集成到共用的父組件,而後在每一個頁面都使用。我也建議這麼作,由於這個共用的父組件其實又不少用處,例如iPhoneX適配等 api
等等,什麼都準備好了,何時須要登陸呢?XX,這個確定是你本身控制的啦。嗯~好吧,咱們來理一理微信
請求接口的時候,嗯~這是你們的共識session
BOSS來了
官方的這張圖已經作了很詳盡的說明,這裏不作贅述
可是看到session_key
了嗎?看到官方同時說的了嗎app
因此問題又來了
誠如上圖
session_key
不失效,只能在每次調用前先使用wx.checkSession
檢查是否有效wx.checkSeesion
很是耗時,大約200ms,因此也不能每次接口調用前都使用wx.checkSession
檢查是否有效wx.login
,由於可能致使正在進行的其它後端任務session_key失效天啦嚕,怎麼辦?!
經過實踐和偶然的發現——官方的示例代碼
得知:在使用小程序期間session_key是不會失效的,so,你想到了什麼?
先問個問題:你準備用什麼方式來存儲校驗的結果?
。。。
讓思考先飛一會
。。。。。。
。。。。。。。。。
。。。。。。。。。。。。
storage嗎?固然能夠,不過不夠完美,爲何?由於storage是永久的存儲,而session_key的有效期卻只是在使用小程序期間,因此你須要在小程序結束後手動重置該狀態以從新校驗其有效性,那是否是在app的onUnload裏重置呢?不是!開發太小程序的應該都知道,那就是結束使用小程序的方式太多,不能保證每種方式都會觸發onUnload,例如用戶直接銷燬了微信進程😳(其實你也能夠在app的onShow裏搞)那用什麼呢?直接用內存啊,藉助內存的自動管理來智能管理,因此最終代碼應該是這樣的
// doRequest.js let wxSessionValid = null // 微信session_key的有效性 // 帶鑑權的請求封裝 async function doRequestWithCheckAuth() { ... if (typeof wxSessionValid !== 'boolean') { wxSessionValid = await checkWxSession() // 檢查微信session是否有效 } if (!wxSessionValid) { await reLogin() // 從新登陸 } wxSessionValid = true // 從新登錄後session_key必定有效 ... }
這樣是否是看起來比較完美了?嗯~
不知道有沒有同窗着急問業務側的session(自定義的登陸態)怎麼沒講?嗯,那如今講吧
其實很簡單,都不想把它做爲一部分來說,但既然講了就必然有我想強調的
校驗微信端的session_key略有麻煩,但不該該把它拋給服務端
而放在前端咱們只須要校驗兩個session的有效性便可,任何一個失效就從新登陸,這是積極主動有效的操做,應該被提倡
OK,基本上梳理的差很少了,就差彈登陸按鈕了,這個簡單,調用剛纔封裝的組件的方法就好了嘛,bingo,但是,點完容許後呢?怎麼繼續用戶的操做呢?怎麼能讓用戶的體驗不被打斷呢?先回放下剛纔reLogin的代碼
async function reLogin() { // 確保有用戶信息 await new Promise(resolve => { // ⚠️注意開頭有await!!! wx.getSetting({ success: (res) => { // 若是用戶沒有受權或者沒有必要的用戶信息 if (!res.authSetting['scope.userInfo'] || !_.isRealTrue(wx.getStorageSync('userInfoRes').userInfo)) { navToLogin(resolve) // 去提示用戶點擊登陸按鈕,⚠️注意:並把當前的resolve帶過去 } else { resolve() // 靜默登陸 } } }) }) return new Promise((resolve) => { wx.login({ success: res => { login(res.code).then((jwt) => { resolve(jwt) // resolve jwt }) // 經過code進行登陸 }, fail(err) { wx.showToast({ title: err.errMsg, icon: 'none', duration: 2000 }) } }) }) } function navToLogin(resolve) { /* eslint-disable no-undef */ const pages = getCurrentPages() const page = pages[pages.length - 1] // 當前page page.openLoginModal(resolve) // 打開登陸按鈕彈框,並把當前的resolve帶過去 }
上面的代碼註釋裏有兩個⚠️注意看到沒?是的,經過回調的方式😂當用戶贊成受權了就繼續餘下的邏輯,若是被拒絕了,則安利他,再拒絕就終止操做,下次須要受權也會繼續彈出受權
有不明白歡迎評論留言指出,我再作說明修改
下一篇文章裏會有代碼呈現,完整源碼之後會放出的,經過wepy搭建的一個框架
下一篇:對api請求封裝的探索和總結謝謝