為了方便小程式應用程式使用微信登入態進行授權登錄,微信小程式提供了登入授權的開放介面。乍看文檔,感覺文檔上講的非常有道理,但是實現起來又真的是摸不著頭腦,不知道如何管理和維護登入態。本文就來手把手的教導大家在業務裡如何接入和維護微信登入態。
存取流程
這裡官方文件上的流程圖已經夠清晰,我們直接就該圖展開詳述和補充。
首先大家看到這張圖,一定會注意到小程式進行通訊互動的不隻小程式前端和我們自己的服務端,微信第三方服務端也參與其中,那麼微信服務端在其中扮演著怎樣的角色呢?我們一起來串一遍登入鑑權的流程就明白了。
1. 呼叫wx.login產生code
wx.login()這個API的作用就是為目前使用者產生一個暫時的登入憑證,這個暫時登入憑證的有效期限只有五分鐘。我們拿到這個登入憑證後就可以進行下一步操作:取得openid和session_key
wx.login({ success: function(loginRes) { if (loginRes.code) { // example: 081LXytJ1Xq1Y40sg3uJ1FWntJ1LXyth } } });
#2. 取得openid和session_key
我們先介紹下openid,用過公眾號的童鞋應該對這個標識都不陌生了,在公眾平台裡,用來標識每個用戶在訂閱號、服務號、小程式這三種不同應用的唯一標識,也就是說每個用戶在每個應用程式的openid都是不一致的,所以在小程式裡,我們可以用openid來識別使用者的唯一性。
那麼session_key是用來幹嘛的呢?有了使用者標識,我們就需要讓該使用者登入,那麼session_key就保證了目前使用者進行會話操作的有效性,而這個session_key是微信服務端給我們所發的。也就是說,我們可以用這個識別來間接維護我們小程式使用者的登入態,那麼這個session_key是怎麼拿到的呢?我們需要在自己的服務端請求微信提供的第三方介面https://api.weixin.qq.com/sns/jscode2session,這個介面需要帶四個參數欄位:
從這幾個參數,我們可以看出,要請求這個介面必須先呼叫wx.login()來取得到使用者目前會話的code。那為什麼我們要在服務端來請求這個介面呢?其實是出於安全性的考量,如果我們在前端透過request呼叫此接口,就不可避免的需要將我們小程式的appid和小程式的secret暴露在外部,同時也將微信服務端下發的session_key暴露給“有心之人”,這對我們的業務安全造成極大的風險。除了需要在服務端進行session_key的獲取,我們還需要注意兩點:
session_key和微信派發的code是一一對應的,同一code只能換取一次session_key。每次呼叫wx.login(),都會下發一個新的code和對應的session_key,為了確保使用者體驗和登入態的有效性,開發者需要清楚使用者需要重新登入時才去呼叫wx.login()
session_key是有失效的,即使是不呼叫wx.login,session_key也會過期,過期時間跟用戶使用小程式的頻率成正相關,但具體的時間長短開發者和用戶都是獲取不到的
function getSessionKey (code, appid, appSecret) { var opt = { method: \'GET\', url: \'https://api.weixin.qq.com/sns/jscode2session\', params: { appid: appid, secret: appSecret, js_code: code, grant_type: \'authorization_code\' } }; return http(opt).then(function (response) { var data = response.data; if (!data.openid || !data.session_key || data.errcode) { return { result: -2, errmsg: data.errmsg || \'返回数据字段不完整\' } } else { return data } }); }
3. 產生3rd_session
#前面說過透過session_key來「間接」地維護登入態,所謂間接,也就是我們需要自己維護使用者的登入態訊息,這裡也是考慮到安全性因素,如果直接使用微信服務端派發的session_key來作為業務方的登錄態使用,會被“有心之人”用來獲取用戶的敏感信息,比如wx.getUserInfo( )這個介面呢,就需要session_key來配合解密微信用戶的敏感資訊。
那麼我們如果生成自己的登錄態標識呢,這裡可以使用幾種常見的不可逆的哈希演算法,例如md5、sha1等,將生成後的登錄態標識(這裡我們統稱為\' skey\')傳回前端,並在前端維護這份登入態標識(一般是存入storage)。而在服務端呢,我們會把生成的skey存在用戶對應的資料表中,前端透過傳遞skey來存取用戶的資訊。
可以看到這裡我們使用了sha1演算法來產生了一個skey:
const crypto = require(\'crypto\'); return getSessionKey(code, appid, secret) .then(resData => { // 选择加密算法生成自己的登录态标识 const { session_key } = resData; const skey = encryptSha1(session_key); }); function encryptSha1(data) { return crypto.createHash(\'sha1\').update(data, \'utf8\').digest(\'hex\') }
4. checkSession##
前面我们将skey存入前端的storage里,每次进行用户数据请求时会带上skey,那么如果此时session_key过期呢?所以我们需要调用到wx.checkSession()这个API来校验当前session_key是否已经过期,这个API并不需要传入任何有关session_key的信息参数,而是微信小程序自己去调自己的服务来查询用户最近一次生成的session_key是否过期。如果当前session_key过期,就让用户来重新登录,更新session_key,并将最新的skey存入用户数据表中。
checkSession这个步骤呢,我们一般是放在小程序启动时就校验登录态的逻辑处,这里贴个校验登录态的流程图:
下面代码即校验登录态的简单流程:
let loginFlag = wx.getStorageSync(\'skey\'); if (loginFlag) { // 检查 session_key 是否过期 wx.checkSession({ // session_key 有效(未过期) success: function() { // 业务逻辑处理 }, // session_key 过期 fail: function() { // session_key过期,重新登录 doLogin(); } }); ) else { // 无skey,作为首次登录 doLogin(); }
推荐:《小程序开发教程》
以上是小程式如何存取和維護微信登入態?的詳細內容。更多資訊請關注PHP中文網其他相關文章!