欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-14 15:49:17
本文实例讲述了微信小程序登录数据解密及状态维持。分享给大家供大家参考,具体如下: 学习过小程序的朋友应该知道,在小程序中是不支持cookie的,借助小程序中的缓存我们也可...

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

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

运行输出

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

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