后端如何解析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