微信小程序支付 登录
登录
openid:
相对于当个微信小程序是唯一的id,但是多个小程序无效
unionid:
对于多个小程序,统一用户的id是相同的(比方说一家公司有多个小程序,那么这个用户在这些小程序的id相同)
登录 登录1,2步实现一步
小程序登录就执行,写在app的生命周期的onLaunch: function () {}
wx.login({ success: res => { wx.request({ url: that.globalData.URL+\'login/\', data:{ code:res.code }, header:{ \'content-type\':\'application/json\' }, method:\'post\', success:function(e){ console.log(e) wx.setStorageSync("token", e.data.data.token) } }) // 发送 res.code 到后台换取 openId, sessionKey, unionId } })二步
const为配置一些常量的文件,注意session_key不可泄露
import requests from settings import const #调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key def login(code): #向url填入参数 url = const.code2Session.format(const.AppId, const.AppSecret, code) reponse = requests.get(url=url) #获取响应的json数据 data = reponse.json() if data.get(\'session_key\'): return data else: return False from django.shortcuts import render from rest_framework.views import APIView from django.core.cache import cache from libs import wx_login import hashlib import time from . import models from rest_framework.response import Response class login(APIView): def post(self,request): #获取请求参数,code param = request.data if param.get("code"): #调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key data = wx_login.login(param.get(\'code\')) if data: #由于不应该把会话密钥下发到小程序,也不应该对外提供这个密钥,所以进行加密处理 # 1 session_key+时间戳等到一个key.(md5 md5 = hashlib.md5() md5.update(data.get("session_key").encode("utf8")) md5.update(str(time.time()).encode("utf8")) key = md5.hexdigest() # 2 session_key与openid做绑定等到val val = data.get("session_key") + \'&\' + data.get("openid") # 3key->val存到redis, cache.set(key, val) # 4把openid存到数据库。用于后续的登录校验 user_data = models.Wxuser.objects.filter(openid=data.get("openid")).first() if not user_data: models.Wxuser.objects.create(openid=data.get("openid")) # 5把key返回给小程序 return Response({"code": 200, "msg": "suc", "data": {"token": key}}) else: return Response({"code": 202, "msg": "code无效"}) else: return Response({"code": 201, "msg": "缺少参数"}) 授权授权
录音授权案例 <button bind:tap="luying">录音</button> luying:function(){ wx.getSetting({ success(res) { console.log("res", res.authSetting[\'scope.record\']) #判断是否已经授权过 if (!res.authSetting[\'scope.record\']) { #弹窗 wx.authorize({ scope: \'scope.record\', #同意授权 success() { // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() }, #不同意授权 fail(){ console.log("你没有授权") } }) }else{ wx.startRecord() } } }) }, 用户信息授权+后端获取用户信息文档
注意:
用户授权和其他授权不一样,他只能通过按钮点击触发
微信不允许明文传输用户信息到后台,必须通过微信提供的sdk解密获取用户的敏感信息
<button open-type="getUserInfo" bindgetuserinfo="info1">获取用户信</button> info1:function(res){ console.log(res,"按钮") #授权成功后,可以随时使用这个获取用户信息 // wx.getUserInfo({ // success: function (res) { // console.log(res, "用户信息") // } // }) var that=this //检查session_key是否过期 wx.checkSession({ success() { //session_key 未过期,并且在本生命周期一直有效 wx.request({ url: app.globalData.URL + "userinfo/", data: { #包括敏感数据在内的完整用户信息的加密数据 encryptedData: res.detail.encryptedData, #加密算法的初始向量 iv: res.detail.iv, #用户token token:wx.getStorageSync("token") }, header: { "content-type": "application/json" }, method: "POST", success: function (e) { console.log(e) } }) }, fail() { // session_key 已经失效,需要重新执行登录流程 // wx.login() //重新登录 } }) },解密SDK
下载官方demo,简单封装,pip install pycryptodome
import base64 import json from Crypto.Cipher import AES from settings import const 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,encryptedData,iv): return cls(const.AppId, sessionKey).decrypt(encryptedData, iv)