zoukankan      html  css  js  c++  java
  • 微信小程序登录数据解密以及状态维持

    学习过小程序的朋友应该知道,在小程序中是不支持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) 

    运行输出

  • 相关阅读:
    超强、超详细Redis入门教程
    zsh: command not found: pip 解决方法
    Python 进阶必备函数
    【debian】解决debian中文安装后出现乱码的问题
    【随笔】关于服务器
    【随笔】Linux主机简单判断CC攻击的命令
    【Docker】通过cookie欺骗在ubuntu中使用wget下载jdk
    【linux】在ubuntu中使用apt-get安装oracle jdk6
    【Nginx】关于域名转发proxy_pass
    【Docker】制作一个支持SSH终端登录的镜像
  • 原文地址:https://www.cnblogs.com/cheesebar/p/6689326.html
Copyright © 2011-2022 走看看