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

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

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

运行输出

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

(0)

相关推荐

  • 微信小程序 登录的简单实现

    微信小程序 实现登录 最近一段时间,微信小程序在张小龙的8小时演讲下瞬间火了起来,但是呢没火多久,就迅速沉静下去了,我也是不知道张小龙什么想法,但是我想法挺多的,好了,废话说多了,聊一下正题吧,我呢是刚入行的小程序员,一路上采坑不断,别人遇不到的坑基本上踩了一遍,话说我的运气有时候也确实挺爆炸的,小程序一个小登录送给大家, 一.小程序开发前准备 目前在网上的教程已经不计其数了,给大家推荐一个网址: http://www.jb51.net/article/111566.htm 这里面介绍比较详细,

  • java实现微信小程序登录态维护的示例代码

    相信不少喜欢开发的朋友都已经知道微信小程序是个什么物种了,楼主也是从小程序内测期间就开始关注,并且也写过几个已经上线的微信小程序.但是基本上都是写的纯前端,最近楼主从后端到前端写一个完整的小程序项目,中间碰到了一些问题,楼主会找一些个人觉得有学习价值的点不定时的拿出来跟大家分享,希望对你有一些帮助. 本次就从最基本的微信小程序登录态维护开始吧.小程序官方api文档里面有对登录态的一个完整的解释,并且有相关的代码.想看详情,可以出门右转:https://mp.weixin.qq.com/debug

  • 微信小程序获取手机号授权用户登录功能

    小程序中有很多地方都会用到注册用户信息的地方,用户需要填写手机号等,有了这个组件可以快速获取微信绑定手机号码,无须用户填写. 1.getPhoneNumber这个组件通过button来实现(别的标签无效).将button中的open-type="getPhoneNumber",并且绑定bindgetphonenumber事件获取回调. <span style="font-size:14px;"><button open-type="get

  • 微信小程序获取循环元素id以及wx.login登录操作

    微信小程序获取循环元素id以及wx.login登录操作 通过点击方法获取循环数据元素的id例: wxml里: <view id="list" wx:for="{{txt}}" > <text id="L_name">{{item.name}}</text> <text id="L_price">¥{{item.price}}/{{item.unit}}</text>

  • 微信小程序 后台登录(非微信账号)实例详解

    微信小程序 后台登录 实现效果图: 最近写了一个工具类的小程序,按需求要求不要微信提供的微信账号登录,需要调取后台登录接口来登录.由于小程序大部分都是调取微信信息登录,很少有调用自己后台来登录的,所以写的时候各种坑,现在把趟好坑的代码共享给大家吧!(PS:如有不妥之处,共勉之.) 废话不说,直接上代码 找到app.js在里面写如下代码 App({ onLaunch: function () { //调用API从本地缓存中获取数据 var logs = wx.getStorageSync('log

  • PHP后台实现微信小程序登录

    微信小程序官方给了十分详细的登陆时序图,当然为了安全着想,应该加上签名加密. 微信小程序端 1).调用wx.login获取 code . 2).调用wx.getUserInfo获取签名所需的 rawData , signatrue , encryptData . 3).发起请求将获取的数据发送的后台. login: function(e) { var that = this; wx.login({ success: function(res){ var code = res.code; //获取

  • 微信小程序 登录实例详解

    微信小程序登录 一. 小程序不支持cookie会话 1. 通过传递与检验3rd_session来保持会话 2. 3rd_session可以执行'`head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 168`该命令生成 3. 使用Redis或者数据库存储session 4. 生成的3rd_session发送给客户端,写入storage 5. 客户端的每次请求必须带上3rd_session 二.加密数据解码 1. $iv,$code是被加密过的数

  • 微信小程序登录状态java后台解密

    一.登录流程图 二.微信小程序端 doLogin:function(callback = () =>{}){ let that = this; wx.login({ success:function(loginRes){ if(loginRes){ //获取用户信息 wx.getUserInfo({ withCredentials:true,//非必填 默认为true success:function(infoRes){ console.log(infoRes,'>>>'); //

  • 微信小程序中做用户登录与登录态维护的实现详解

    总结 大家都知道,在开发中提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户登录,标识用户和获取用户信息,以用户为核心提供服务,是大部分小程序都会做的事情.我们今天就来了解下在小程序中,如何做用户登录,以及如何去维护这个登录后的会话(Session)状态.下面来看看详细的介绍: 在微信小程序中,我们大致会涉及到以下三类登录方式: 自有的账号注册和登

  • 微信小程序 本地存储及登录页面处理实例详解

    实例内容 登陆界面 处理登陆表单数据 处理登陆表单数据(异步) 清除本地数据 登录界面: 在app.json中添加登陆页面pages/login/login,并设置为入口. 保存后,自动生成相关文件(挺方便的). 修改视图文件login.wxml <!--pages/login/login.wxml--> <view class="container"> <form bindsubmit="formSubmit"> <vie

随机推荐