不知不覺已經一個月沒有寫東西了,墮落的日子居然過的這么心(chou)安(bu)理(yao)得(lian),罪過啊。 好了,回到正文來,聊咱們的小程序。 致敬登錄大部分邏輯代碼統統來自 手把手教會你小程序登錄鑒權 登錄流程上圖是官方給出的登錄流程,我們來捋下邏輯。 1、用戶使用 wx.login 獲取臨時 code ,有效期為5分鐘 2、將臨時 code 傳到我們自己的后端服務,調用微信的API獲取用戶的 session_key 和 openid 3、后端自定義新的密鑰并關聯返回的 session_key 和 openid ,將新的密鑰返給前端 4、前端發送請求的時候,帶著密鑰,后端進行解析后返回數據 session_key和openid1、 session_key 會話密鑰,用來確定會話的操作的有效性和用來加密解密用戶數據,服務器自己存儲即可,不應該將密鑰返給前端和對話使用 2、 openid 用戶唯一標識,同樣只用于服務器,可以用來標識用戶的唯一性 接下來,我們說下它們的獲取,通過服務端調用微信API獲取 API: https://api.weixin.qq.com/sns/jscode2session 參數如下: ![]() // 小程序頁面 wx.login({ success:(ret)=>{ wx.request({ url: 'http://test.com', // 后端服務器 data:{ code : ret.code } }) } }) 后端服務我們使用 request 模塊來發送請求 // 后端服務 let options = { url: 'https://api.weixin.qq.com/sns/jscode2session', qs:{ appid: appid, secret: secret, js_code: code, grant_type:'authorization_code' } } // 默認請求方式是get request(options, (err, response, body) => { if(err) return err return body // {openid:'openid', session_key:'session_key'} 不是真正的返回 看下面的代碼 }) 生成新的密鑰 skey上面我們獲取了session_key和openid,下文兩個字斷稱keyID,接下來我們生成一個新的密鑰返回前端并將新密鑰關聯keyID。 我們使用crypto模塊的sha1算法生成密鑰 const crypto = require('crypto') function getShaKey(data){ return crypto.createHash('sha1').update(data, 'utf8').digest('hex') } 上面的代碼返回我們就改成這個新的skey,前端將這個密鑰存在storage里面,請求的時候帶上這個skey,就完成了自定義登錄態。 wx.checkSession用來校驗當前用戶的session_key是否有效,微信不會把session_key的有效期告知開發者,用戶越頻繁使用小程序,session_key有效期越長。 wx.checkSession({ success:function(){ // 當前session_key有效 ... // 可以寫我們的業務代碼 }, fail:function(){ // 當前session_key已過期 wx.login() // 重新登錄,獲取新的session_key } }) 當session_key過期的時候,我們調用登錄API,更新session_key生成新的skey,并關聯二者關系。 工具函數的封裝前面我們將流程大概串了下,接下來我們把上面的流程寫成寫成公用的函數 // 驗證session_key狀態 function checkSession(){ return new Promise((resolve, reject) => { wx.checkSession({ success:function(){ resolve(true) }, fail:function(){ reject(false) } }) }) } // 登錄 function login(){ return new Promise((resolve, reject) => { wx.login({ success: (ret) => { wx.request({ url:'本地服務地址', method: 'POST', data:{ code: ret.code }, success: (response) =>{ wx.setStorageSync('skey', response.data.key) // 將skey存在storage里面 resolve(response.data.key) } }) } }) }) } // 請求 function ajax(url, data, method="GET", config={}){ let skey = wx.getStorageSync('skey') // 獲取skey if(!skey){ // 沒有skey,首次登錄 return new Promise((resolve, reject) => { login() reject('請登錄') }) } else { return new Promise((resolve, reject) => { checkSession().then( _=> { if (_){ // session_key有效 wx.request({ url, method: method.toLocaleUpperCase(), data, header: Object.assign({}, { skey }, config), success: (ret) => { resolve(ret.data) } }) } else { // session_key失效 login() reject('session_key失效') } }) }) } } 后端代碼后端使用koa框架,代碼見文末 github 地址 解密官方提供了多種編程語言的示例代碼點擊下載 這里我們使用微信運動API為例 var app = getApp() // 我們將工具函數都放在了app的示例上面 Page({ onLoad:function(){ app.Util.login().then(_ => { // 先登錄然后獲取數據 this.getrunData() }) }, getrunData(){ wx.getWeRunData({ success: (ret) => { app.Util.ajax('本地服務地址', { iv: ret.iv, data: ret.encryptedData}, 'post').then(_=>{ console.log(_) }, (err)=>{ console.log(err) }) } }) }, }) 返回結果如下 以上,我們完成了小程序簡單的登錄鑒權和數據解密 結尾登錄鑒權我們只是將用戶狀態放在了內存里,實際項目中肯定要放在數據庫中,可以拜讀下大神文章,里面說到了數據庫的操作。 再次致敬 |