❥微信小程序❥----授权
首先先说我们的 获取用户地址 wx.chooseAddress 获取用户收货地址。调起用户编辑收货地址原生界面,并在编辑完成后返回用户选择的地址。调用前需要用户授权
wx.authorize
提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。更多用法详见 用户授权。
对就是这里用户的授权 唯一和 wx.chooseAddress不一样的是 有了一个参数 scope
scope | 需要获取权限的 scope,详见 scope 列表 |
示例代码:
authorize:function(){ // 通过getSetting来获取用户的授权 wx.getSetting({ success(res){ console.log(res) // 判断用户的授权中有没有record 没有 // 说明没有授权 那就启动我们的授权 if(!res.authSetting['scope.record']){ wx.authorize({ // 这里的scope就是我们需要授权的功能 scope: 'scope.record', // 如果成功说明用户已经点击授权了所以我们 // 调用语音接口 success(res){ wx.startRecord() } }) } } }) }
这里是我们的scope列表 ==点击==
wx.getUserInfo
那么我们开始掉用户信息表 调用前需要 用户授权 scope.userInfo
withCredentials | 是否带上登录态信息。当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。 |
lang | 显示用户信息的语言 |
success回调函数的参数
userInfo | 用户信息对象,不包含 openid 等敏感信息 | |
rawData | 不包括敏感信息的原始数据字符串,用于计算签名 | |
signature |
|
|
encryptedData | 包括敏感数据在内的完整用户信息的加密数据,详见 用户数据的签名验证和加解密 | |
iv | 加密算法的初始向量,详见 用户数据的签名验证和加解密 | |
cloudID |
|
但是我这里想说 所有的授权都可以使用wx.authorize 来调起 但是我们的 userinfo 不行 必须使用一个按钮来调起
补充: wx.authorize 是用来调起弹框的 而 你的 startrecord 才是真正的授权
也就是说 我把 startrecord注释了 他还是会调起 弹框 但是 不会 真正的授权
想要调起用户信息必须open-type 指定为 getUserInfo 且 bindgetuserinfo
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>
登陆授权
from rest_framework.views import APIView from rest_framework.response import Response from app01.wx import setting import requests import time, hashlib from django.core.cache import cache from app01 import models # 获取login_key def get_secret_key(data): now = time.time() key = str(now) + data md5 = hashlib.md5() md5.update(key.encode('utf-8')) return md5.hexdigest() class Login(APIView): def post(self, request, *args, **kwargs): # 获取code code = request.data.get('code') # 发起获取openid session_key请求 url = setting.URL.format(setting.APP_ID,setting.APP_SECRET,code) try: session_key, open_id = list(requests.get(url).json().values()) # 拿到我们的session和open_id 后 本地保存 自定义登陆状态返回 except: return Response({'status':404, 'msg':"登陆失败"}) secret_key = get_secret_key(open_id) secret_value = f"{session_key}&{open_id}" # 保存redis数据库 cache.set(secret_key, secret_value) # 判断用户是否是第一次登陆 user_obj = models.Wxuser.objects.filter(openid=open_id).first() if not user_obj: # 没有就创建 models.Wxuser.objects.create(openid=open_id) return Response({'status':200 , 'msg':'登陆成功', 'token':secret_key})
用户数据获取接口
全部写代码了哈, 都有注释的.
下面是 微信小程序 获取到用户的头像带有表情包的设置 同时数据库也要是utf8mb4
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'userinfo_demo', 'USER':'root', 'PASSWORD':'123', 'OPTIONS':{'charset':'utf8mb4'} } }
getuser:function(res){ console.log(res) // 校验用户的session是否过期 // 如果过期的话那就 从新让用户授权 wx.checkSession({ success(){ // 或者使用wx.getUserInfo来获取数据 wx.getUserInfo({ success(res){ // 这里的 res 和上面的 res都是一样的 console.log(res) // 然后把这些信息发送给后台 wx.request({ url: app.globalData.url+'/get_userinfo/', method:'POST', header:{'content-type':'application/json'}, // 携带上我们的 login_key data: { 'encryptedData':res.encryptedData, 'iv': res.iv, 'login_key':wx.getStorageSync('login_key') }, success(res){ console.log(res) }, fail(res){ console.log(res, '用户数据获取失败') } }) } }) }, fail(){ this.login() } })
from rest_framework.serializers import ModelSerializer class GetUserInfoModelSerializer(ModelSerializer): class Meta: model = models.Wxuser fields = '__all__' # 获取用户信息 class GetUserInfo(APIView): def post(self,request, *args, **kwargs): token = request.data.get('login_key') iv = request.data.get('iv') encryptedData = request.data.get('encryptedData') # 判断是否缺少参数 if not (token and iv and encryptedData): return Response({"status":404,'msg':'缺少参数'}) # 拿到我们的session和openid session_key, open_id = cache.get(token).split('&') # 解密用户数据 data = WXBizDataCrypt.get_info(session_key,iv,encryptedData) save_data = { "name": data['nickName'], "avatar": data['avatarUrl'], "language": data['language'], "province": data['province'], "city": data['city'], "country": data['country'], } # 更新数据库 models.Wxuser.objects.filter(openid=open_id).update(**save_data) user_obj = models.Wxuser.objects.filter(openid=open_id).first() data = GetUserInfoModelSerializer(instance=user_obj,many=False).data print(data) return Response({"status":200,'msg':'请求成功', 'data':data})
import base64 from . import setting import json from Crypto.Cipher import AES 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, session_key, iv, encryptedData): return WXBizDataCrypt(setting.APP_ID, session_key).decrypt(encryptedData, iv)
趁自己还没死 多折腾折腾