商城系統(tǒng) 注冊(cè)

唱吧小程序登錄授權(quán)頁(yè)面開發(fā)

2018-08-20|HiShop
導(dǎo)讀:基本的流程不用多說(shuō),按部就班即可,就是使用wx.login()可以獲得開發(fā)者服務(wù)器向微信接口服務(wù)器請(qǐng)求獲得sessionkey等數(shù)據(jù)時(shí)所需要的參數(shù)code,開發(fā)者服務(wù)器...

基本的流程不用多說(shuō),按部就班即可,就是使用wx.login()可以獲得開發(fā)者服務(wù)器向微信接口服務(wù)器請(qǐng)求獲得sessionkey等數(shù)據(jù)時(shí)所需要的參數(shù)code,開發(fā)者服務(wù)器以code+appid+appsecret換取用戶唯一標(biāo)識(shí)openid和會(huì)話密鑰sessionkey。但每一次調(diào)用wx.login()都會(huì)更新微信接口服務(wù)器上的session_key。

同樣,改造微信api先,


  1. // wechat 登錄封裝

  2. const login = () => {

  3.    return new Promise((resolve, reject) => {

  4.      wx.login({ success: resolve, fail: reject })

  5.    })

  6. }

而后,在做自己的登錄封裝時(shí),可以先去請(qǐng)求微信的code,然后用在自己的請(qǐng)求中,獲取并存儲(chǔ)自己的登錄態(tài)。


  1. let we_login = await wechat.login() // 微信登錄

  2. let cb_login = await requestAPI('xxxx/checkCode', { data: {code: we_login.code}})

  3. if (cb_login && cb_login.code === 1) {

  4.      // xxxx 業(yè)務(wù)邏輯

  5.  } catch (error) {

  6.    wx.showModal({

  7.      title: '登錄提示',

  8.      content: '登錄失敗',

  9.      showCancel: false

  10.    })

  11.  }

而在完成上面整套業(yè)務(wù)邏輯過(guò)程中,可能會(huì)遇到一些意想不到的坑,這里面我印象比較深刻的有兩個(gè),第一個(gè)是關(guān)于授權(quán)的問(wèn)題,另一個(gè)就是關(guān)于小程序生命周期與頁(yè)面生命周期初始化過(guò)程中異步請(qǐng)求回調(diào)順序的問(wèn)題。

  • 授權(quán)問(wèn)題

先說(shuō)第一個(gè)問(wèn)題,關(guān)于授權(quán)框喚起的問(wèn)題,只有用戶授權(quán)后,才可以進(jìn)一步獲取用戶的信息,這個(gè)框在最初是可以通過(guò)wx.getUserinfo()方法直接喚起,而在5月份以后,微信去掉了這個(gè)方法的功能,只能通過(guò)固定的button open-type去引導(dǎo)用戶授權(quán)。

 

所以在底層邏輯的設(shè)計(jì)過(guò)程中,就要拋棄之前l(fā)ogin之后獲取用戶授權(quán)信息的設(shè)計(jì)思路,而是進(jìn)行拆分,將login和授權(quán)的邏輯分開。

在必須要授權(quán)操作的地方例如我們小程序中需要“參賽”或者“關(guān)注”的地方,進(jìn)行單獨(dú)授權(quán)的處理,通過(guò)使用wx.getSetting獲取用戶的授權(quán)情況 1) 如果用戶已經(jīng)授權(quán),直接調(diào)用wx.getUserInfo獲取用戶最新的信息 2) 用戶未授權(quán),在界面中顯示一個(gè)按鈕提示用戶登入,當(dāng)用戶點(diǎn)擊并授權(quán)后就獲取到用戶的最新信息。

  • onLaunch和onLoad異步回調(diào)順序問(wèn)題

這個(gè)問(wèn)題簡(jiǎn)單來(lái)說(shuō),就是小程序啟動(dòng)有自己的生命周期onLaunch->onShow->onHide,而每個(gè)page的實(shí)例化也有自己的生命周期,onLoad->onShow->onReady->onHide->onUnload

然而在開發(fā)過(guò)程中,會(huì)遇到這種情況,在App啟動(dòng)onLaunch的時(shí)候,發(fā)起登錄請(qǐng)求,并注冊(cè)到我們自己的服務(wù)器上以便使用,這個(gè)過(guò)程中,

app on launch -> request -> success -> page onload

是無(wú)法判斷success和page onload哪個(gè)先,會(huì)導(dǎo)致頁(yè)面初始化數(shù)據(jù)失敗的情況,為了解決這個(gè)問(wèn)題,我們團(tuán)隊(duì)也是想到了幾種常見的解決方案。

解決方案一 就是在request success中處理,使用getCurrentPages方法獲取是否頁(yè)面先于success生成,如果生成我們就強(qiáng)制讓頁(yè)面再次渲染。

這顯然是一種hack的方式, 在實(shí)際使用過(guò)程當(dāng)中,如果登錄邏輯比較復(fù)雜,這個(gè)方法不是十分便利,page onload在一些特殊情況也會(huì)被調(diào)用,這顯然不是我們想看到的


  1. if (getCurrentPages().length != 0) {

  2.    getCurrentPages()[getCurrentPages().length - 1].onLoad()

  3. }

解決方案二(目前我在開發(fā)中使用的是這種方案)

在login的邏輯里,增加一個(gè)回調(diào)函數(shù)cbLoginCallBack。

Page頁(yè)面判斷一下當(dāng)前app.globalData.sessionKey是否存在,如果沒(méi)有(第一次)則定義定義一個(gè)app方法(回調(diào)函數(shù))


  1. // Login Request

  2.    if (app.cbLoginCallBack) {

  3.        typeof app.cbLoginCallBack == 'function' && app.cbLoginCallBack(cb_login.data)

  4.    }

  5. // 邏輯頁(yè)面

  6. if (app.globalData.sessionkey) {

  7.    // init data

  8.    } else {

  9.    app.cbLoginCallBack = res => {

  10.        if (res) {

  11.        // init data

  12.        }

  13. } }

App頁(yè)面在請(qǐng)求success后判斷時(shí)候有Page頁(yè)面定義的回調(diào)方法,如果有就執(zhí)行該方法。因?yàn)榛卣{(diào)函數(shù)是在Page里面定義的所以方法作用域this是指向Page頁(yè)面。

HiShop小程序工具提供多類型商城/門店小程序制作,可視化編輯 1秒生成5步上線。通過(guò)拖拽、拼接模塊布局小程序商城頁(yè)面,所看即所得,只需要美工就能做出精美商城。更多小程序商店請(qǐng)查看:小程序商店

電話咨詢 預(yù)約演示 0元開店