微信小程序登錄數(shù)據(jù)解密及狀態(tài)維持實(shí)例詳解
本文實(shí)例講述了微信小程序登錄數(shù)據(jù)解密及狀態(tài)維持。分享給大家供大家參考,具體如下:
學(xué)習(xí)過(guò)小程序的朋友應(yīng)該知道,在小程序中是不支持cookie的,借助小程序中的緩存我們也可以存儲(chǔ)一些信息,但是對(duì)于一些比較重要的信息,我們需要通過(guò)登錄狀態(tài)維持來(lái)保存,同時(shí),為了安全起見(jiàn),用戶(hù)的敏感信息,也是需要加密在網(wǎng)絡(luò)上傳輸?shù)摹?/p>
前臺(tái),service。封裝了http請(qǐng)求,同時(shí)封裝了getSession(通過(guò)code獲取服務(wù)器生成的session)、getUserInfo(獲取用戶(hù)信息)、getDecryptionData(解密數(shù)據(jù))
//service.js //封裝了http服務(wù),getUserInfo,提供回調(diào)函數(shù) var recourse = { doMain: "http://www.domain.com/" } module.exports = { //Http Get requestGet: function (url, data, cb) { wx.request({ url: recourse.doMain + url, data: data, method: 'GET', header: {}, success: function (res) { cb(res, true) }, fail: function () { cb(data, false) } }) }, //Http POST requestPost: function (url, data, cb) { wx.request({ url: recourse.doMain + url, data: data, method: 'POST', header: {}, success: function (res) { cb(res, true) }, fail: function () { cb(data, false) } }) }, //獲取第三方sessionId getSession: function (code, cb) { wx.request({ url: recourse.doMain + 'SmallRoutine/PostCode', data: { code: code }, method: 'POST', success: function (res) { cb(res, true) }, fail: function (res) { cb(res, false) } }) }, //獲取用戶(hù)信息 getUserInfo: function (cb) { wx.getUserInfo({ success: function (res) { cb(res, true) }, fail: function (res) { cb(res, false) } }) }, //獲取解密數(shù)據(jù) getDecryptionData: function (cb) { wx.request({ url: recourse.doMain+'SmallRoutine/Decryption', data: { encryptedData: wx.getStorageSync('encryptedData'), iv: wx.getStorageSync('iv'), session: wx.getStorageSync('thirdSessionId'), }, method: 'POST', success: function (res) { cb(res, true) }, fail: function (res) { cb(res, false) } }) } }
后臺(tái),根據(jù)code獲取session,客戶(hù)端用來(lái)保持登錄狀態(tài)
[HttpPost] public ActionResult PostCode(string code) { try { if(!string.IsNullOrEmpty(code)) { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code",appId,appSecret,code)); request.Method = "GET"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream()); string content = sr.ReadToEnd(); if(response.StatusCode == HttpStatusCode.OK) { var successModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeSuccess>(content); if(null != successModel.session_key) { //session_key是微信服務(wù)器生成的針對(duì)用戶(hù)數(shù)據(jù)加密簽名的密鑰,不應(yīng)該傳輸?shù)娇蛻?hù)端 var session_key = successModel.session_key; //3re_session用于服務(wù)器和小程序之間做登錄狀態(tài)校驗(yàn) var thirdSession = Guid.NewGuid().ToString().Replace("-",""); var now = DateTime.Now; //存到數(shù)據(jù)庫(kù)或者redis緩存,這里一小時(shí)過(guò)期 Service.AddLogin(new Domain.Login() { Code = code, Createime = now, OpenId = successModel.openid, OverdueTime = now.AddMinutes(60), SessionKey = successModel.session_key, SessionRd = thirdSession }); return Json(new { success = true,session = thirdSession,openId = successModel.openid }); } else { var errModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeFail>(content); return Json(new { success = false,msg = errModel.errcode + ":" + errModel.errmsg }); } } else { var errModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeFail>(content); return Json(new { success = false,msg = errModel.errcode + ":" + errModel.errmsg }); } } else { return Json(new { success = false,msg = "code不能為null" }); } } catch(Exception e) { return Json(new { success = false }); } }
解密敏感信息
[HttpPost] public ActionResult Decryption(string encryptedData,string iv,string session) { try { var sessionKey = Service.GetSessionKey(session); if(!string.IsNullOrEmpty(sessionKey)) { var str = AESDecrypt(encryptedData,sessionKey,iv); var data = Newtonsoft.Json.JsonConvert.DeserializeObject<EncryptedData>(str); if(null != data) { //服務(wù)器可以更新用戶(hù)信息 return Json(new { success = true,data = data }); } } } catch(Exception e) { Service.AddLog("翻譯錯(cuò)誤:"+e.ToString()); } return Json(new { success = false }); }
AES解密
public static string AESDecrypt(string encryptedData,string key,string iv) { if(string.IsNullOrEmpty(encryptedData)) return ""; byte[] encryptedData2 = Convert.FromBase64String(encryptedData); System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged { Key = Convert.FromBase64String(key), IV = Convert.FromBase64String(iv), Mode = System.Security.Cryptography.CipherMode.CBC, Padding = System.Security.Cryptography.PaddingMode.PKCS7 }; System.Security.Cryptography.ICryptoTransform ctf = rm.CreateDecryptor(); Byte[] resultArray = ctf.TransformFinalBlock(encryptedData2,0,encryptedData2.Length); return Encoding.UTF8.GetString(resultArray); }
判斷用戶(hù)是否掉線(xiàn)
[HttpPost] public ActionResult PostSession(string session) { if(!string.IsNullOrEmpty(session)) { var loginInfo = Service.GetLoginInfo(session); if(null != loginInfo) { return Json(new { success = true,openId = loginInfo.OpenId }); } else { return Json(new { success = false }); } } return Json(new { success = false }); }
前臺(tái)index.js
//index.js var app = getApp() Page({ data: { userInfo: {}, }, onLoad: function () { var that = this app.getUserInfo(function (userInfo) { //更新數(shù)據(jù) that.setData({ userInfo: userInfo }) }) } })
前臺(tái)app.js
var service = require('./service/service.js') var appConfig = { getUserInfo: function (cb) { var that = this if (that.globalData.userInfo) { //從緩存中用戶(hù)信息 } else { //wx api 登錄 wx.login({ success: function (res) { console.log('登錄成功 code 為:' + res.code); if (res.code) { service.getSession(res.code, function (res, success) { if (success) { console.log('通過(guò) code 獲取第三方服務(wù)器 session 成功, session 為:' + res.data.session); //緩存起來(lái) wx.setStorageSync('thirdSessionId', res.data.session); //wx api 獲取用戶(hù)信息 service.getUserInfo(function (res, success) { if (success) { console.log('獲取用戶(hù)信息成功, 加密數(shù)據(jù)為:' + res.encryptedData); console.log('獲取用戶(hù)信息成功, 加密向量為:' + res.iv); //緩存敏感的用戶(hù)信息,解密向量 wx.setStorageSync('encryptedData', res.encryptedData); wx.setStorageSync('iv', res.iv); that.globalData.userInfo = res.userInfo; //解密數(shù)據(jù) service.getDecryptionData(function (res, success) { if (success) { console.log("解密數(shù)據(jù)成功"); console.log(res.data.data); } else { console.log('解密數(shù)據(jù)失敗'); } }) } else { console.log('獲取用戶(hù)信息失敗') } }); } else { console.log('通過(guò) code 獲取第三方服務(wù)器 session 失敗'); } }); } else { console.log('登錄失敗:'); } } }) } }, globalData: { userInfo: null } } App(appConfig)
運(yùn)行輸出
希望本文所述對(duì)大家微信小程序開(kāi)發(fā)有所幫助。
相關(guān)文章
深入理解ES6 Promise 擴(kuò)展always方法
本篇文章主要介紹了ES6 Promise 擴(kuò)展always方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09webpack 3.X學(xué)習(xí)之多頁(yè)面打包的方法
這篇文章主要介紹了webpack 3.X學(xué)習(xí)之多頁(yè)面打包的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09JS簡(jiǎn)單獲取當(dāng)前年月日星期的方法示例
這篇文章主要介紹了JS簡(jiǎn)單獲取當(dāng)前年月日星期的方法,結(jié)合完整實(shí)例形式分析了javascript基于自定義函數(shù)獲取當(dāng)前日期時(shí)間的方法,涉及javascript中Date()類(lèi)的使用與日期相關(guān)運(yùn)算技巧,需要的朋友可以參考下2017-02-02swiper+echarts實(shí)現(xiàn)多個(gè)儀表盤(pán)左右滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了swiper+echarts實(shí)現(xiàn)多個(gè)儀表盤(pán)左右滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06深入認(rèn)識(shí)JavaScript中的函數(shù)
深入認(rèn)識(shí)JavaScript中的函數(shù)...2007-01-01bootstrap table實(shí)現(xiàn)點(diǎn)擊翻頁(yè)功能 可記錄上下頁(yè)選中的行
這篇文章主要介紹了bootstrap table實(shí)現(xiàn)點(diǎn)擊翻頁(yè)功能,可記錄上下頁(yè)選中的行,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09