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

说明:本文没有找到原文地址 
学习过小程序的朋友应该知道,在小程序中是不支持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
      })
    })
  }
})

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

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

     
     
  1. //service.js
  2. //封装了http服务,getUserInfo,提供回调函数
  3. var recourse = {
  4. doMain: "http://www.domain.com/"
  5. }
  6. module.exports = {
  7. //Http Get
  8. requestGet: function (url, data, cb) {
  9. wx.request({
  10. url: recourse.doMain + url,
  11. data: data,
  12. method: 'GET',
  13. header: {},
  14. success: function (res) {
  15. cb(res, true)
  16. },
  17. fail: function () {
  18. cb(data, false)
  19. }
  20. })
  21. },
  22. //Http POST
  23. requestPost: function (url, data, cb) {
  24. wx.request({
  25. url: recourse.doMain + url,
  26. data: data,
  27. method: 'POST',
  28. header: {},
  29. success: function (res) {
  30. cb(res, true)
  31. },
  32. fail: function () {
  33. cb(data, false)
  34. }
  35. })
  36. },
  37. //获取第三方sessionId
  38. getSession: function (code, cb) {
  39. wx.request({
  40. url: recourse.doMain + 'SmallRoutine/PostCode',
  41. data: { code: code },
  42. method: 'POST',
  43. success: function (res) {
  44. cb(res, true)
  45. },
  46. fail: function (res) {
  47. cb(res, false)
  48. }
  49. })
  50. },
  51. //获取用户信息
  52. getUserInfo: function (cb) {
  53. wx.getUserInfo({
  54. success: function (res) {
  55. cb(res, true)
  56. },
  57. fail: function (res) {
  58. cb(res, false)
  59. }
  60. })
  61. },
  62. //获取解密数据
  63. getDecryptionData: function (cb) {
  64. wx.request({
  65. url: recourse.doMain+'SmallRoutine/Decryption',
  66. data: {
  67. encryptedData: wx.getStorageSync('encryptedData'),
  68. iv: wx.getStorageSync('iv'),
  69. session: wx.getStorageSync('thirdSessionId'),
  70. },
  71. method: 'POST',
  72. success: function (res) {
  73. cb(res, true)
  74. },
  75. fail: function (res) {
  76. cb(res, false)
  77. }
  78. })
  79. }
  80. }

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

     
     
  1. [HttpPost]
  2. public ActionResult PostCode(string code)
  3. {
  4. try
  5. {
  6. if(!string.IsNullOrEmpty(code))
  7. {
  8. 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));
  9. request.Method = "GET";
  10. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  11. StreamReader sr = new StreamReader(response.GetResponseStream());
  12. string content = sr.ReadToEnd();
  13. if(response.StatusCode == HttpStatusCode.OK)
  14. {
  15. var successModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeSuccess>(content);
  16. if(null != successModel.session_key)
  17. {
  18. //session_key是微信服务器生成的针对用户数据加密签名的密钥,不应该传输到客户端
  19. var session_key = successModel.session_key;
  20. //3re_session用于服务器和小程序之间做登录状态校验
  21. var thirdSession = Guid.NewGuid().ToString().Replace("-","");
  22. var now = DateTime.Now;
  23. //存到数据库或者redis缓存,这里一小时过期
  24. Service.AddLogin(new Domain.Login()
  25. {
  26. Code = code,
  27. Createime = now,
  28. OpenId = successModel.openid,
  29. OverdueTime = now.AddMinutes(60),
  30. SessionKey = successModel.session_key,
  31. SessionRd = thirdSession
  32. });
  33. return Json(new { success = true,session = thirdSession,openId = successModel.openid });
  34. }
  35. else
  36. {
  37. var errModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeFail>(content);
  38. return Json(new { success = false,msg = errModel.errcode + ":" + errModel.errmsg });
  39. }
  40. }
  41. else
  42. {
  43. var errModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ValidateCodeFail>(content);
  44. return Json(new { success = false,msg = errModel.errcode + ":" + errModel.errmsg });
  45. }
  46. }
  47. else
  48. {
  49. return Json(new { success = false,msg = "code不能为null" });
  50. }
  51. }
  52. catch(Exception e)
  53. {
  54. return Json(new { success = false });
  55. }
  56. }

解密敏感信息

     
     
  1. [HttpPost]
  2. public ActionResult Decryption(string encryptedData,string iv,string session)
  3. {
  4. try
  5. {
  6. var sessionKey = Service.GetSessionKey(session);
  7. if(!string.IsNullOrEmpty(sessionKey))
  8. {
  9. var str = AESDecrypt(encryptedData,sessionKey,iv);
  10. var data = Newtonsoft.Json.JsonConvert.DeserializeObject<EncryptedData>(str);
  11. if(null != data)
  12. {
  13. //服务器可以更新用户信息
  14. return Json(new { success = true,data = data });
  15. }
  16. }
  17. }
  18. catch(Exception e)
  19. {
  20. Service.AddLog("翻译错误:"+e.ToString());
  21. }
  22. return Json(new { success = false });
  23. }

AES解密

     
     
  1. public static string AESDecrypt(string encryptedData,string key,string iv)
  2. {
  3. if(string.IsNullOrEmpty(encryptedData)) return "";
  4. byte[] encryptedData2 = Convert.FromBase64String(encryptedData);
  5. System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
  6. {
  7. Key = Convert.FromBase64String(key),
  8. IV = Convert.FromBase64String(iv),
  9. Mode = System.Security.Cryptography.CipherMode.CBC,
  10. Padding = System.Security.Cryptography.PaddingMode.PKCS7
  11. };
  12. System.Security.Cryptography.ICryptoTransform ctf = rm.CreateDecryptor();
  13. Byte[] resultArray = ctf.TransformFinalBlock(encryptedData2,0,encryptedData2.Length);
  14. return Encoding.UTF8.GetString(resultArray);
  15. }

判断用户是否掉线

     
     
  1. [HttpPost]
  2. public ActionResult PostSession(string session)
  3. {
  4. if(!string.IsNullOrEmpty(session))
  5. {
  6. var loginInfo = Service.GetLoginInfo(session);
  7. if(null != loginInfo)
  8. {
  9. return Json(new { success = true,openId = loginInfo.OpenId });
  10. }
  11. else
  12. {
  13. return Json(new { success = false });
  14. }
  15. }
  16. return Json(new { success = false });
  17. }

前台index.js

     
     
  1. //index.js
  2. var app = getApp()
  3. Page({
  4. data: {
  5. userInfo: {},
  6. },
  7. onLoad: function () {
  8. var that = this
  9. app.getUserInfo(function (userInfo) {
  10. //更新数据
  11. that.setData({
  12. userInfo: userInfo
  13. })
  14. })
  15. }
  16. })

前台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)







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值