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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM