微信小程式的登入體系

杜俊成要好好學習發表於2019-02-15

普通的web服務維護登入態

微信小程式的登入體系

我們知道,WEB伺服器通過瀏覽器攜帶的cookie獲取session來判斷是否是同一使用者(或瀏覽器)。

cookie 和 session 的區別

  1. cookiesession 並不是同一個層面的東西。

  2. cookie 是實際真實存在的一個東西,是http協議規定的,如同一種載體,我們可以在響應頭裡面設定 cookie,只要你願意,你可以在cookie裡面設定任何東西,不管是使用者資訊使用者暱稱, 但是這樣有安全性風險,cookie裡面不適合有敏感性的資訊,比如說,只放session_id

  3. session 是一個抽象概念,是客戶端和服務端保持會話的一種方法,一種通用的機制。session 的意思是會話,實現是:服務端把一個唯一標識和使用者身份的對應的關係儲存下來,存在redis, 檔案資料庫中都可以。客戶端出的請求帶上唯一標識,服務端從redis 或者 檔案或者 資料庫中找出這個唯一標識 對應的身份,這種機制就被稱為session

  4. session 機制大部分使用cookie 作為載體運送這個唯一標識,也可以採用url 連線、 自定義請求頭來實現。

    微信小程式的登入體系

小程式登入態

對於小程式來說,也需要一個唯一的識別符號來區分使用者,也就是session來保持會話,但是小程式沒有cookie, 因此我們的唯一識別符號會被儲存在 localstorage 裡面,每次發請求時,都會從localStorage 裡面拿到這個唯一識別符號,帶在請求中。

微信的openidcode

在日常開發中,我們也經常聽到openidcode的概念。

openid 用來標識這個唯一的微信使用者,也就是說,一個微信使用者相對於一個公眾號(主體)的openid 是唯一的,是不會變的。

那麼我們如何才能知道 某一個使用者的 openid 呢?

就是通過code, 對於同一個使用者,每次獲取到的 code 都會改變,有有效期。我們把code 作為引數,呼叫指定的微信伺服器的介面,就可以拿到使用者的openid

那麼我們如何才能拿到 code 呢?

微信內h5頁面的方法是:跳到指定的微信的承接頁面,再跳回到本頁面,url連結上就會被拼上code

小程式的方法是: 通過呼叫 wx.login() 方法,就可以拿到使用者的code

知道了上面的前提條件,就可以去實現一個微信小程式的登入體系。

微信小程式登入體系

微信小程式的登入體系

  1. 通過 wx.login() 獲取到使用者的code

  2. 通過wx.request() 方法請求我們自己的後端,我們自己的服務端把appid, appsecretcode 一起傳送到微信伺服器。 appidappsecret 都是微信提供的,可以在管理員後臺找到

  3. 微信伺服器返回了 openid

  4. 我們在自己的資料庫中,查詢openid ,如果沒有查到記錄,說明該使用者沒有註冊,如果有記錄,則繼續往下走

  5. 我們生成一個第三方session, 也就是session_id, 也就是使用者唯一識別符號。在redis中,把session_id 和使用者的身份存進去。

  6. 返回 3rd_session

  7. 小程式把3rd_session存到 storage 裡面

  8. 下次請求時,先從 storage 裡面讀取,然後帶給服務端

  9. 服務端從redis 裡面找到3rd_session 對應的記錄,然後校驗有效期

問題一:

為什麼我們要自己維護一個使用者資料庫,實現一個註冊體系?用微信的不好嗎?

因為我們業務不光是在微信裡面玩,比如說,在app的場景下,我們肯定沒有辦法通過微信這一套來登入。

問題二:

為什麼仍需設定前端的登入態,而不是每次用小程式的code換open_id?

因為用code換open_id的方式,需要等待wx.login() 獲取code, 需要等待node端請求微信伺服器用code換取open_id。 相比於直接直接帶上登入態,使用者等待時間更長。

獲取使用者資訊

最新版小程式中,只需要一個按鈕就可以獲取到使用者的資訊

微信小程式的登入體系

 獲取頭像暱稱 
複製程式碼

微信規定需要指定該btn的open-typegetUserInfo, 使用者資訊會放在getUserInfo的回撥函式裡面。

如果使用者之前沒有授權過,則會彈出彈窗授權。

如果使用者已經授權過,則不需要彈出彈窗授權。

通過 wx.getSetting 方法可以獲取到使用者的授權資訊

wx.getSetting({
            success(res) {
                if (!res || !res.authSetting) {
                    wx.showToast({
                        title: '查詢授權失敗',
                    })
                    return;
                }
                this.setData({
                    authInfo: res.authSetting
                })
            }
        })
複製程式碼

註冊體系

微信小程式的登入體系

關鍵性細節

資料庫設計

微信小程式的登入體系

其他

  1. 微信小程式沒有遇到跨域的問題。原因:wx.request() 請求其實是先走到了微信伺服器,然後微信伺服器再請求的第三方伺服器,相當於起到了代理伺服器的作用。

相關文章