小程序后端如何解析wx.getUserInfo中的用户信息

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

猜你喜欢

转载自www.cnblogs.com/godlover/p/12509822.html