開發微信小程序時,接入小程序的受權登陸能夠快速實現用戶註冊登陸的步驟,是快速創建用戶體系的重要一步。這篇文章將介紹 python + flask + 微信小程序實現用戶快速註冊登陸方案(本文主要進行後端邏輯的梳理,小程序端邏輯只寫了必要的部分,若有須要,請點擊鏈接閱讀官方開發文檔)html
官方給出的微信小程序登陸時序圖以下:python
這個流程分爲兩大部分:redis
小程序經過**wx.login**獲取微信的 code,而後將這個 code 發送給開發者服務器。算法
返回值數據庫
屬性 | 類型 | 說明 |
---|---|---|
code | String | 用戶容許登陸後,回調內容會帶上 code(有效期五分鐘) |
小程序端能夠經過 wx.getSetting 接口獲取用戶當前的受權狀態json
引導用戶關注公衆號
來得到受權。小程序端調用 wx.getUserInfo API 來得到用戶信息(該接口的調用須要得到用戶受權)flask
接口success 時返回參數以下:小程序
參數名 | 類型 | 說明 |
---|---|---|
userInfo | OBJECT | 用戶信息對象,不包含 openid 等敏感信息。 |
rawData | String | 不包括敏感信息的原始數據字符串,用於計算簽名。 |
signature | String | 使用 sha1( rawData + sessionkey ) 獲得字符串,用於校驗用戶信息 |
encryptedData | String | 包括敏感數據在內的完整用戶信息的加密數據,詳細見加密數據解密算法 |
iv | String | 加密算法的初始向量,詳細見加密數據解密算法 |
將這些第一步得到的js_code
和這裏得到的 rawData
, signature
, encryptedData
, iv
一塊兒打包傳入開發者後端。segmentfault
開發者服務器接收到 code
以後,會進行封裝處理,經過**code2Session**這個api接口來獲取真正須要的微信用戶的登陸態session_key
和 openid
和 unionid
。後端
session_key
纔是真正的微信登陸態信息,可是把 openid
和 unionid
加起來一塊兒理解,也能夠籠統地理解爲這些都是微信的登陸態信息。請求參數
屬性 | 類型 | 默認值 | 必填 | 說明 |
---|---|---|---|---|
appid | string | 是 | 小程序 appId | |
secret | string | 是 | 小程序 appSecret | |
js_code | string | 是 | 登陸時獲取的 code | |
grant_type | string | 是 | 受權類型,此處只需填寫 authorization_code |
返回值(返回JSON數據包)
屬性 | 類型 | 說明 |
---|---|---|
openid | string | 用戶惟一標識 |
session_key | string | 會話密鑰 |
unionid | string | 用戶在開放平臺的惟一標識符,在知足 UnionID 下發條件的狀況下會返回 |
errcode | number | 錯誤碼 |
errmsg | string | 錯誤信息 |
這時,服務器須要判斷返回的JSON數據包是否包含unionid:
encryptedData
解密後爲如下 json 結構,詳見加密數據解密算法
{ "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } }
解密腳本實例鏈接:https://res.wx.qq.com/wxdoc/dist/assets/media/aes-sample.eae1f364.zip
爲了確保開放接口返回用戶數據的安全性,微信會對明文數據進行簽名。開發者能夠根據業務須要對數據包進行簽名校驗,確保數據的完整性。
code
爲空,返回登陸失敗。code
不爲空,且 rawData
不爲空,須要進行簽名校驗:
code
,appid
、app_secret
請求code2session接口得到 session_key
和 openid
ERR_SESSION_KEY_EXCHANGE_FAILED
rawData
和 session_key
計算簽名 signature2
signature
和 signature2
ERR_UNTRUSTED_RAW_DATA
rawData
爲 wxUserInfo
openid
寫入到 wxUserInfo
(code, wxUserInfo)
緩存到 Rediscode
不爲空,但 rawData
爲空,從 Redis 根據 code
查詢緩存的用戶信息
ERR_SESSION_EXPIRED
開發者服務器須要本身生成一個自定義的登陸態(例如業務 token或者 session)來保存這些微信服務器返回來的微信登陸態相關信息(session_key
和 openid
和 unionid
),而且作關聯處理,而後返回給小程序客戶端。
小程序客戶端接收到返回的自定義登陸態信息,從而判斷用戶是否登陸成功,登陸成功的話,就將自定義登陸態信息保存到本地的存儲。到這裏,登陸就完成了。
app.globaldata
,也能夠是 localstoage
,注意,小程序不支持 cookie
。小程序客戶端訪問業務接口的時候,攜帶以前保存到本地存儲的自定義登陸態信息進行對開發者服務器(業務接口服務器)訪問。
開發者服務器的業務接口接收到請求,而且請求裏面攜帶了自定義的登陸態,經過校驗以後,會返回相關信息。
校驗登陸是將小程序客戶端攜帶過來的自定義登陸態和開發者服務器緩存起來的自定義登陸態進行對比,會去確認是否和用戶的 openid
或者 unionid
和 session_key
相匹配。
code2Session
進行微信登陸態更新。因爲咱們的小程序使用微信號做爲小程序的帳號,若是須要使用自定義的帳號,則須要再加上註冊的api和關聯帳號的邏輯。
code
是微信用戶的登陸臨時憑證,是打開小程序登陸的時候獲取的只屬於這個微信用戶的登陸憑證,須要注意的是,這個登陸憑證只供微信小程序使用的。且同一個每一次登陸時得到的code都不一樣。這個 code
的存活時間通常是5分鐘左右,他的最大做用就是肯定是來源自哪個微信用戶來打開,是爲了後續生成一個微信登陸態 session_key
而準備的。session_key
是微信用戶在小程序裏面的登陸態信息,這是微信給這個用戶頒發的一個登陸 session
。這個session
一直存活直到你關閉小程序。
expire_time
的,可是後面取消了,官方的解釋是:用戶越頻繁使用小程序,session_key有效期越長,初始有效期是3天,可是這個不必定是固定的,具體看業務需求,總的原則就是維護一個自定義登陸態,自定義登陸須要和微信登陸態關聯。openId
,用戶在微信裏面的惟一標識,可是須要跟 unionid
進行一塊兒理解。unioinId
,若是開發者擁有多個移動應用、網站應用、和公衆賬號(包括小程序),可經過unionid
來區分用戶的惟一性,由於只要是同一個微信開放平臺賬號下的移動應用、網站應用和公衆賬號(包括小程序),用戶的unionid
是惟一的。換句話說,同一用戶,對同一個微信開放平臺下的不一樣應用,unionid
是相同的。
openId
就是微信用戶的惟一標識,可是由於微信產品不少,因此會出現多個微信產品使用不一樣的 openId
來識別同一個用戶,因此建議是統一使用 unioinid
做爲用戶識別的依據,由於通常來講,通常的業務都會有公衆號,因此 unionid
使用頻率較高。3rd_session
是通常是指開發者服務器的登陸態,本文中並無使用這個概念,而是叫作自定義登陸態或者直接說JWTtoken,官方文檔或者其餘一些博客中會提到它。實際上他們是相同的概念。
wx.checkSession
來檢查,若是過時了,就本地執行登陸操做,再讓開發者服務器跟微信服務器交互,獲取新的小程序登陸態,而後關聯到自定義登陸態。若是每次打開小程序都須要用戶來登陸顯然是不合適的,若是用戶上一次的登陸態尚未過時,則應該視用戶爲已經登陸。若是過時,才須要用戶從新登陸。
有2種方式來作:
wx.checkSession
檢查微信登陸態是否過時:
某些業務須要只有用戶登陸狀態下才能夠執行,因此,咱們須要封裝一個api來驗證用戶時候登陸
實際上就是檢查一下微信和自定義的登陸態是否過時