更新說明:
由於微信小程式官方對相關API的改版,所以登入這塊功能流程有一些變動,因此最近再次更新了另一篇文章(附影片說明和完整範例程式碼),大家可與本文一起進行閱讀參考:
微信小程式介面改版後的登入與會話保持流程
提供使用者登入以及維護使用者的登入狀態,是一個擁有使用者係統的軟體應用普遍需要做的事情。像微信這樣的一個社交平台,如果做一個小程式應用,我們可能很少會去做一個完全脫離和捨棄連接用戶資訊的純工具軟體。
讓使用者登錄,標識使用者和獲取使用者訊息,以使用者為核心提供服務,是大部分小程式都會做的事情。我們今天就來了解下在小程式中,如何做使用者登錄,以及如何去維護這個登入後的會話(Session)狀態。
在微信小程式中,我們大致會涉及以下三類登入方式:
第一和第二種方式是目前Web應用中最常見的兩種方式,在微信小程式中同樣可以使用,但是需要值的注意的是,小程式中沒有Cookie
的機制,所以在使用這2種方式前,請確認你們或第三方的API是否需要依賴Cookie
;還有小程式中也不支援HTML頁面,那些需要使用頁面重定向來進行登入的第三方API就需要改造,或不能用了。
我們今天主要來討論第三種方式,即如何使用微信帳號進行登錄,因為這種方式和微信平台結合最緊密,用戶體驗比較好。
引用小程式官方文件的登入流程圖,整個登入流程基本上如下圖所示:
該圖中,「小程式」指的就是我們使用小程式框架寫的程式碼部分,「第三方伺服器」一般就是我們自己的後台服務程序,「微信伺服器」是微信官方的API伺服器。
下面我們來逐步分解一下這個流程圖。
登入憑證(code)
在小程式中登入的第一步,就是先取得登入憑證。我們可以使用wx.login()方法並且得到一個登入憑證。
我們可以在小程式的App程式碼中發起登入憑證要求,也可以在其他任何Page頁面程式碼中發起登入憑證要求,主要根據你小程式的實際需求。
App({ onLaunch: function() { wx.login({ success: function(res) { var code = res.code; if (code) { console.log('获取用户登录凭证:' + code); } else { console.log('获取用户登录态失败:' + res.errMsg); } } }); } })
唯一標識(openid)
和會話金鑰(session_key)
首先,我們使用wx.request()方法,請求我們自己實作的一個後台API,並將登入憑證(code)攜帶過去,例如在我們前面程式碼的基礎上增加:
App({ onLaunch: function() { wx.login({ success: function(res) { var code = res.code; if (code) { console.log('获取用户登录凭证:' + code); // --------- 发送凭证 ------------------ wx.request({ url: 'https://www.my-domain.com/wx/onlogin', data: { code: code } }) // ------------------------------------ } else { console.log('获取用户登录态失败:' + res.errMsg); } } }); } })
你的後台服務(/wx/onlogin)接著需要使用這個傳遞過來的登入憑證,去呼叫微信介面換取openid和session_key,介面位址格式如下:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
這裡是我使用了Node.js Express建立的後台服務的程式碼,僅供參考:
router.get('/wx/onlogin', function (req, res, next) { let code = req.query.code request.get({ uri: 'https://api.weixin.qq.com/sns/jscode2session', json: true, qs: { grant_type: 'authorization_code', appid: '你小程序的APPID', secret: '你小程序的SECRET', js_code: code } }, (err, response, data) => { if (response.statusCode === 200) { console.log("[openid]", data.openid) console.log("[session_key]", data.session_key) //TODO: 生成一个唯一字符串sessionid作为键,将openid和session_key作为值,存入redis,超时时间设置为2小时 //伪代码: redisStore.set(sessionid, openid + session_key, 7200) res.json({ sessionid: sessionid }) } else { console.log("[error]", err) res.json(err) } }) })
這段後台程式碼成功執行的話,就可以得到openid和session_key。這個資訊就是目前微信帳號在微信伺服器那邊的登入態了。
但是,為了安全方面的原因,請不要直接使用這些資訊作為你小程式的使用者標識和session標識回傳到小程式客戶端中去,我們應該在伺服器端做一層自己的session,將這個微信帳號登入態產生一個session id並維護在我們自己的session機制中,然後把這個session id派發到小程式客戶端當作session標識來使用。
關於如何在伺服器端做這個session機制,我們現在一般會採用鍵值對儲存工具來做,例如redis。我們為每個session產生一個唯一的字串作為鍵,然後可以將session_key和openid作為值,存入redis中,為了安全,存入的時候還應設定一個超時的時間。
sessionid
開發Web應用程式的時候,在客戶端(瀏覽器)中,我們通常會將session id存放在cookie中,但小程式沒有cookie機制,所以不能採用cookie了,但小程式有本地的storage,所以我們可以使用storage來保存sessionid,以供後續的後台API呼叫所使用。
在之后,调用那些需要登录后才有权限的访问的后台服务时,你可以将保存在storage中的sessionid取出并携带在请求中(可以放在header中携带,也可以放在querystring中,或是放在body中,根据你自己的需要来使用),传递到后台服务,后台代码中获取到该sessionid后,从redis中查找是否有该sessionid存在,存在的话,即确认该session是有效的,继续后续的代码执行,否则进行错误处理。
这是一个需要session验证的后台服务示例,我的sessionid是放在header中传递的,所以在这个示例中,是从请求的header中获取sessionid:
router.get('/wx/products/list', function (req, res, next) { let sessionid = req.header("sessionid") let sessionVal = redisStore.get(sessionid) if (sessionVal) { // 执行其他业务代码 } else { // 执行错误处理 } })
好了,通过微信账号进行小程序登录和状态维护的简单流程就是这样,了解这些知识点之后,再基于此进行后续的开发就会变得更容易了。
另外,腾讯前端团队也开源了他们封装的相关库Wafer,可以借鉴和使用。
感谢阅读我的文章,如有疑问或写错的地方请不吝留言赐教。
一斤代码的《微信小程序》相关教程文章
一斤代码的《从编程小白到全栈开发》系列教程文章
推荐教程:《Vue.js教程推荐:最新的5个vue.js视频教程精选》
以上是在微信小程式中使用者登入和登入狀態維護的詳細內容。更多資訊請關注PHP中文網其他相關文章!