后端如何解析wx.getUserInfo中的用户信息
1.必须是登入状态,因为要用到encryedData和iv,进行解密,必须使用session_key
2.session_key是有有效期的,而且session_key的有效期,不是一个固定值,而是通过用户的行为来决定
3.可以通过wx.checkSession来判断有没有过期
4.保证session_key没有过期的情况下,我们将iv,encryptedData,token(登入凭证)发送到后端
5.后端使用官方提供的sdk,进行解密
6.解密成功后保存到数据,数据库的字符集一定要是utf8mb4,同时django数据库配置中要加'OPTIONS': {'charset': 'utf8mb4'}
ps: 在页面中的this指的是页面对象,在app中的this指的是app对象
代码:
小程序的test.js中
user:function(e){
console.log("e",e.detail)
wx.getSetting({
success(res){
if (res.authSetting['scope.userInfo']){
wx.checkSession({
success() {
//session_key 未过期,并且在本生命周期一直有效
wx.getUserInfo({
success: (res) => {
// console.log("res",res) 这个res里就是用户的信息
// 将这个数据发送给后端
wx.request({
// 这里是来发送iv和encrytedData
url: app.globalData.baseurl+'getinfo/',
data:{
iv:res.iv,
encrypedData:res.encryptedData,
token:wx.getStorageSync('token')
},
method:"POST",
success: (e) => {
console.log("后台返回的数据", e)
}
})
}
})
},
fail() {
// session_key 已经失效,需要重新执行登录流程
app.my_login() //重新登录
wx.getUserInfo({
success: (res) => {
// console.log("res",res) 这个res里就是用户的信息
// 将这个数据发送给后端
wx.request({
// 这里是来发送iv和encrytedData
url: app.globalData.baseurl + 'getinfo/',
data: {
iv: res.iv,
encrypedData: res.encryptedData,
token: wx.getStorageSync('token')
},
method: "POST",
success: (e) => {
console.log("后台返回的数据", e)
}
})
}
})
}
})
}
}
})
},
后端中urls.py
url(r'^getinfo/', user.Info.as_view())
user.py
from rest_framework.response import Response
from rest_framework.views import APIView
from app01.wx import wx_login
import hashlib
import time
from django.core.cache import cache
from app01.models import Wxuser
from app01.wx import WXBizDataCrypt
class Info(APIView):
def post(self, request):
param = request.data
# print(param)
if param.get("iv") and param.get("encrypedData") and param.get("token"):
session_key_openid = cache.get(param.get("token"))
if session_key_openid:
session_key, openid = session_key_openid.split("&")
user_info = WXBizDataCrypt.WXBizDataCrypt.get_info(session_key, param.get("encrypedData"), param.get("iv"))
print("user_info", user_info)
save_data = {
"name": user_info["nickName"],
"avatar": user_info["avatarUrl"],
"language": user_info["language"],
"province": user_info["province"],
"country": user_info["country"],
"city": user_info["city"],
}
Wxuser.objects.filter(openid=openid).update(**save_data)
return Response({
"status": 0,
"msg": "ok",
"data": save_data
})
else:
return Response({"code": 2, "msg": "无效的token"})
else:
return Response({"code": 1, "msg": "缺少参数!"})
WXBizDataCrypt.py
import base64
import json
from Crypto.Cipher import AES
from app01.wx import settings
class WXBizDataCrypt:
def __init__(self, appId, sessionKey):
self.appId = appId
self.sessionKey = sessionKey
def decrypt(self, encryptedData, iv):
# base64 decode
sessionKey = base64.b64decode(self.sessionKey)
encryptedData = base64.b64decode(encryptedData)
iv = base64.b64decode(iv)
cipher = AES.new(sessionKey, AES.MODE_CBC, iv)
decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData)))
if decrypted['watermark']['appid'] != self.appId:
raise Exception('Invalid Buffer')
return decrypted
def _unpad(self, s):
return s[:-ord(s[len(s) - 1:])]
@classmethod
def get_info(cls, sessionKey, encrypedData, iv):
return cls(settings.AppId, sessionKey).decrypt(encrypedData, iv)
如果要存表情:
如果没有Crypto包:
pip install pycryptodome