普通的web服務維護登入態
我們知道,WEB伺服器通過瀏覽器攜帶的cookie獲取session來判斷是否是同一使用者(或瀏覽器)。
cookie 和 session 的區別
-
cookie
和session
並不是同一個層面的東西。 -
cookie
是實際真實存在的一個東西,是http協議規定的,如同一種載體,我們可以在響應頭裡面設定 cookie,只要你願意,你可以在cookie裡面設定任何東西,不管是使用者資訊使用者暱稱, 但是這樣有安全性風險,cookie裡面不適合有敏感性的資訊,比如說,只放session_id
-
session
是一個抽象概念,是客戶端和服務端保持會話的一種方法,一種通用的機制。session
的意思是會話
,實現是:服務端把一個唯一標識和使用者身份的對應的關係儲存下來,存在redis
,檔案
,資料庫
中都可以。客戶端出的請求帶上唯一標識,服務端從redis
或者檔案
或者資料庫
中找出這個唯一標識 對應的身份,這種機制就被稱為session
-
session
機制大部分使用cookie
作為載體運送這個唯一標識,也可以採用url 連線、 自定義請求頭來實現。
小程式登入態
對於小程式來說,也需要一個唯一的識別符號來區分使用者,也就是session來保持會話,但是小程式沒有cookie, 因此我們的唯一識別符號會被儲存在 localstorage
裡面,每次發請求時,都會從localStorage
裡面拿到這個唯一識別符號,帶在請求中。
微信的openid
和code
在日常開發中,我們也經常聽到openid
和code
的概念。
openid
用來標識這個唯一的微信使用者,也就是說,一個微信使用者相對於一個公眾號(主體)的openid
是唯一的,是不會變的。
那麼我們如何才能知道 某一個使用者的 openid
呢?
就是通過code
, 對於同一個使用者,每次獲取到的 code
都會改變,有有效期。我們把code
作為引數,呼叫指定的微信伺服器的介面,就可以拿到使用者的openid
。
那麼我們如何才能拿到 code
呢?
微信內h5頁面的方法是:跳到指定的微信的承接頁面,再跳回到本頁面,url連結上就會被拼上code
。
小程式的方法是: 通過呼叫 wx.login()
方法,就可以拿到使用者的code
知道了上面的前提條件,就可以去實現一個微信小程式的登入體系。
微信小程式登入體系
-
通過
wx.login()
獲取到使用者的code
-
通過
wx.request()
方法請求我們自己的後端,我們自己的服務端把appid
,appsecret
和code
一起傳送到微信伺服器。appid
和appsecret
都是微信提供的,可以在管理員後臺找到 -
微信伺服器返回了
openid
-
我們在自己的資料庫中,查詢
openid
,如果沒有查到記錄,說明該使用者沒有註冊,如果有記錄,則繼續往下走 -
我們生成一個第三方session, 也就是session_id, 也就是使用者唯一識別符號。在redis中,把session_id 和使用者的身份存進去。
-
返回
3rd_session
-
小程式把
3rd_session
存到 storage 裡面 -
下次請求時,先從
storage
裡面讀取,然後帶給服務端 -
服務端從redis 裡面找到
3rd_session
對應的記錄,然後校驗有效期
問題一:
為什麼我們要自己維護一個使用者資料庫,實現一個註冊體系?用微信的不好嗎?
因為我們業務不光是在微信裡面玩,比如說,在app的場景下,我們肯定沒有辦法通過微信這一套來登入。
問題二:
為什麼仍需設定前端的登入態,而不是每次用小程式的code換open_id?
因為用code換open_id的方式,需要等待wx.login() 獲取code, 需要等待node端請求微信伺服器用code換取open_id。 相比於直接直接帶上登入態,使用者等待時間更長。
獲取使用者資訊
最新版小程式中,只需要一個按鈕就可以獲取到使用者的資訊
獲取頭像暱稱
複製程式碼
微信規定需要指定該btn的open-type
為 getUserInfo
, 使用者資訊會放在getUserInfo
的回撥函式裡面。
如果使用者之前沒有授權過,則會彈出彈窗授權。
如果使用者已經授權過,則不需要彈出彈窗授權。
通過 wx.getSetting
方法可以獲取到使用者的授權資訊
wx.getSetting({
success(res) {
if (!res || !res.authSetting) {
wx.showToast({
title: '查詢授權失敗',
})
return;
}
this.setData({
authInfo: res.authSetting
})
}
})
複製程式碼
註冊體系
關鍵性細節
資料庫設計
其他
- 微信小程式沒有遇到跨域的問題。原因:wx.request() 請求其實是先走到了微信伺服器,然後微信伺服器再請求的第三方伺服器,相當於起到了代理伺服器的作用。