JavaScript

超轻量级php框架startmvc

微信小程序登录数据解密及状态维持实例详解

更新时间:2020-08-25 00:12:01 作者:startmvc
本文实例讲述了微信小程序登录数据解密及状态维持。分享给大家供大家参考,具体如下:

本文实例讲述了微信小程序登录数据解密及状态维持。分享给大家供大家参考,具体如下:

学习过小程序的朋友应该知道,在小程序中是不支持cookie的,借助小程序中的缓存我们也可以存储一些信息,但是对于一些比较重要的信息,我们需要通过登录状态维持来保存,同时,为了安全起见,用户的敏感信息,也是需要加密在网络上传输的。

前台,service。封装了http请求,同时封装了getSession(通过code获取服务器生成的session)、getUserInfo(获取用户信息)、getDecryptionData(解密数据)


//service.js
//封装了http服务,getUserInfo,提供回调函数
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)
 }
 })
 },
 //获取用户信息
 getUserInfo: function (cb) {
 wx.getUserInfo({
 success: function (res) {
 cb(res, true)
 },
 fail: function (res) {
 cb(res, false)
 }
 })
 },
 //获取解密数据
 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)
 }
 })
 }
}

后台,根据code获取session,客户端用来保持登录状态


[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是微信服务器生成的针对用户数据加密签名的密钥,不应该传输到客户端
 var session_key = successModel.session_key;
 //3re_session用于服务器和小程序之间做登录状态校验
 var thirdSession = Guid.NewGuid().ToString().Replace("-","");
 var now = DateTime.Now;
 //存到数据库或者redis缓存,这里一小时过期
 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)
 {
 //服务器可以更新用户信息
 return Json(new { success = true,data = data });
 }
 }
 }
 catch(Exception e)
 {
 Service.AddLog("翻译错误:"+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);
}

判断用户是否掉线


[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 });
}

前台index.js


//index.js
var app = getApp()
Page({
 data: {
 userInfo: {},
 },
 onLoad: function () {
 var that = this
 app.getUserInfo(function (userInfo) {
 //更新数据
 that.setData({
 userInfo: userInfo
 })
 })
 }
})

前台app.js


var service = require('./service/service.js')
var appConfig = {
 getUserInfo: function (cb) {
 var that = this
 if (that.globalData.userInfo) {
 //从缓存中用户信息
 } 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('通过 code 获取第三方服务器 session 成功, session 为:' + res.data.session);
 //缓存起来
 wx.setStorageSync('thirdSessionId', res.data.session);
 //wx api 获取用户信息
 service.getUserInfo(function (res, success) {
 if (success) {
 console.log('获取用户信息成功, 加密数据为:' + res.encryptedData);
 console.log('获取用户信息成功, 加密向量为:' + res.iv);
 //缓存敏感的用户信息,解密向量
 wx.setStorageSync('encryptedData', res.encryptedData);
 wx.setStorageSync('iv', res.iv);
 that.globalData.userInfo = res.userInfo;
 //解密数据
 service.getDecryptionData(function (res, success) {
 if (success) {
 console.log("解密数据成功");
 console.log(res.data.data);
 } else {
 console.log('解密数据失败');
 }
 })
 } else {
 console.log('获取用户信息失败')
 }
 });
 } else {
 console.log('通过 code 获取第三方服务器 session 失败');
 }
 });
 } else {
 console.log('登录失败:');
 }
 }
 })
 }
 },
 globalData: {
 userInfo: null
 }
}
App(appConfig)

运行输出

希望本文所述对大家微信小程序开发有所帮助。

微信小程序 登录数据 解密 状态维持