對於微信而言, 小程序算是第三方了, 那么, 小程序是如何登錄的呢? 微信肯定不能把密碼給小程序, 讓小程序來登錄啊, 小程序甚至無法獲取微信的微信號。 在這里, 我們需要徹底把微信和小程序分開, 割裂來看, 才好理解。
那小程序是怎樣來登錄的呢? 這就涉及到微信開放平台了。我們知道, 很多網站支持QQ登錄, 支持微博登錄, 也支持微信登錄。 這種借賬號體系的行為, 我們早就討論過, 無需贅述。 我們知道, 每個用微信的人, 都一個微信號, 那么從微信中進入小程序, 就需要一個什么號來標識這個小程序, 這就是openID, 對於同一個小程序而言, 不同用戶的openID是不一致的, 這在oAuth協議中有介紹。
下面, 我們來看看小程序的登錄過程。
小程序調用wx.login函數, 獲取與這個用戶對應的code(js_code), 然后把這code帶給小程序后台, 於是乎小程序后台就拿到了區別於用戶的code, 這實際上是微信給小程序的一個登錄態標志, 有點像token/session, 其實不是像, 而是是。 雖然每個用戶的code不一樣, 但當然不能以這個作為區分每個用戶的標志啊, 因為code會變化(過期), 所以思來想去, 還是用與微信號有一一對應關系的openID更為靠譜。
來一起看看微信公眾平台的介紹:
wx.login(OBJECT)
調用接口獲取登錄憑證(code)進而換取用戶登錄態信息,包括用戶的唯一標識(openid) 及本次登錄的 會話密鑰(session_key)等。用戶數據的加解密通訊需要依賴會話密鑰完成。
注:調用 login
會引起登錄態的刷新,之前的 sessionKey 可能會失效。
OBJECT參數說明:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
success | Function | 否 | 接口調用成功的回調函數 |
fail | Function | 否 | 接口調用失敗的回調函數 |
complete | Function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行) |
success返回參數說明:
參數名 | 類型 | 說明 |
---|---|---|
errMsg | String | 調用結果 |
code | String | 用戶登錄憑證(有效期五分鍾)。開發者需要在開發者服務器后台調用 api,使用 code 換取 openid 和 session_key 等信息 |
示例代碼:
-
//app.js
-
App({
-
onLaunch: function() {
-
wx.login({
-
success: function(res) {
-
if (res.code) {
-
//發起網絡請求
-
wx.request({
-
url: 'https://test.com/onLogin',
-
data: {
-
code: res.code
-
}
-
})
-
} else {
-
console.log('獲取用戶登錄態失敗!' + res.errMsg)
-
}
-
}
-
});
-
}
-
})
code 換取 session_key
這是一個 HTTPS 接口,開發者服務器使用登錄憑證 code 獲取 session_key 和 openid。
session_key 是對用戶數據進行加密簽名的密鑰。為了自身應用安全,session_key 不應該在網絡上傳輸。
接口地址:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
請求參數:
參數 | 必填 | 說明 |
---|---|---|
appid | 是 | 小程序唯一標識 |
secret | 是 | 小程序的 app secret |
js_code | 是 | 登錄時獲取的 code |
grant_type | 是 | 填寫為 authorization_code |
返回參數:
參數 | 說明 |
---|---|
openid | 用戶唯一標識 |
session_key | 會話密鑰 |
unionid | 用戶在開放平台的唯一標識符。本字段在滿足一定條件的情況下才返回。具體參看UnionID機制說明 |
返回說明:
-
//正常返回的JSON數據包
-
{
-
"openid": "OPENID",
-
"session_key": "SESSIONKEY",
-
"unionid": "UNIONID"
-
}
-
//錯誤時返回JSON數據包(示例為Code無效)
-
{
-
"errcode": 40029,
-
"errmsg": "invalid code"
-
}
wx.checkSession(OBJECT)
通過上述接口獲得的用戶登錄態擁有一定的時效性。用戶越久未使用小程序,用戶登錄態越有可能失效。反之如果用戶一直在使用小程序,則用戶登錄態一直保持有效。具體時效邏輯由微信維護,對開發者透明。開發者只需要調用wx.checkSession接口檢測當前用戶登錄態是否有效。登錄態過期后開發者可以再調用wx.login獲取新的用戶登錄態。
OBJECT參數說明:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
success | Function | 否 | 接口調用成功的回調函數,登錄態未過期 |
fail | Function | 否 | 接口調用失敗的回調函數,登錄態已過期 |
complete | Function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行) |
示例代碼:
-
wx.checkSession({
-
success: function(){
-
//session 未過期,並且在本生命周期一直有效
-
},
-
fail: function(){
-
//登錄態過期
-
wx.login() //重新登錄
-
....
-
}
-
})
登錄態維護
通過 wx.login
獲取到用戶登錄態之后,需要維護登錄態。
開發者要注意不應該直接把 session_key、openid 等字段作為用戶的標識或者 session 的標識,而應該自己派發一個 session 登錄態(請參考登錄時序圖)。對於開發者自己生成的 session,應該保證其安全性且不應該設置較長的過期時間。session 派發到小程序客戶端之后,可將其存儲在 storage ,用於后續通信使用。
通過 wx.checkSession
可以檢測用戶登錄態是否失效。並決定是否調用 wx.login
重新獲取登錄態
登錄時序圖
值得注意的是, code可以認為是微信給小程序的一個登錄態票據, 而3rd_session則是小程序后台給小程序的登錄態票據。 在后續的會話中, 真正的主角是小程序和小程序后台, 所有的業務邏輯應該圍繞小程序和小程序后台展開,微信和微信后台退居幕后(只能提供了開放登錄接口的能力、和基礎的api功能而已)
在后續的讀寫訪問中, 3rd_session作為登錄態票據, 來訪問小程序后台, 執行對應的動作。 小程序后台則要進行登錄態校驗。
其實, 很簡單。