[转]微信小程序登录数据解密以及状态维持
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转]微信小程序登录数据解密以及状态维持相关的知识,希望对你有一定的参考价值。
本文转自:http://www.cnblogs.com/cheesebar/p/6689326.html
学习过小程序的朋友应该知道,在小程序中是不支持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)
运行输出
分类: 小程序
以上是关于[转]微信小程序登录数据解密以及状态维持的主要内容,如果未能解决你的问题,请参考以下文章