openid:是用单个微信应用表示用户的唯一标识。亚洲:饼哥小程序上openid :123,那该用户再张成的小程序上他的opendid不是123,是其他任意一个值,上面的意思:同一用户再不用不同应用上的openid不同,但是再同一应用上唯一。
场景: 假设你们公司有2个小程序。但是你们老板想把用户做统一处理。比如新用户登入任意一个小程序,就发送发送礼包。但是只要再一个小程序上另过了,就不能再另一个上面领取。
unionnid:一个用户在多个小程序有唯一的标识 (几个小程序号在微信小程序网上进行绑定)
登录授权时序
1 小程序端执行wx.login()获取code 2 将1中的code发送到后端,后端调用auth.code2Session这个接口,得到openid和session_key 3 自定义登入状态,我们生成一个key与openid和session_key相绑定。把key返回到小程序中 4 小程序端保存,然后下次请求需要登入的接口的时候,把key带上。
微信前端app.js
App({ /* 当小程序初始化完成,会触发onlaunch(全局只触发一次) */ onLaunch: function () { let that = this // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res.code) wx.request({ url: that.globalData.baseurl+\'login/\', data:{\'code\':res.code}, method:"POST", success(e){ wx.setStorageSync(\'token\', e.data.data.token) // 保存token值到本地 } }) } })
下面为django项目:settings.py
import pymysql pymysql.install_as_MySQLdb() DATABASES = { \'default\': { \'ENGINE\': \'django.db.backends.mysql\', \'NAME\': \'python13\', \'USER\':\'root\', \'PASSWORD\':\'\', \'HOST\':\'127.0.0.1\', \'PORT\': 3306, #\'OPTIONS\': {\'charset\': \'utf8mb4\'}, } } CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/0", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100}, "DECODE_RESPONSES": True, "PASSWORD": "admin123", } } }
models.py
from django.db import models # Create your models here. class Wxuser(models.Model): id = models.AutoField(primary_key=True) openid=models.CharField(max_length=255) name = models.CharField(max_length=50) avatar = models.CharField(max_length=200) language = models.CharField(max_length=50) province = models.CharField(max_length=50) city = models.CharField(max_length=50) country = models.CharField(max_length=50) #gender = models.CharField(max_length=50) creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.openid
wx/settings.py
AppId="..." AppSecret=\'...\' code2Session = \'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code\'
此处去查AppId, AppSecret
wx/wx_login.py
from app01.wx import settings import requests def get_login_info(code): code_url = settings.code2Session.format(settings.AppId,settings.AppSecret,code) response = requests.get(code_url) json_response = response.json() # 把json格式数据转换为字典 print("json_response",json_response) if json_response.get("session_key"): return json_response else: return False
views/user.py
from rest_framework.views import APIView from rest_framework.response import Response from app01.wx import wx_login from django.core.cache import cache import hashlib,time from app01.models import Wxuser class Login(APIView): def post(self,request): param = request.data if not param.get("code"): return Response({"status":1,"msg":"缺少参数"}) else: code = param.get("code") user_data = wx_login.get_login_info(code) if user_data: val = user_data[\'session_key\'] +"&"+user_data[\'openid\'] md5 = hashlib.md5() md5.update(str(time.clock()).encode("utf-8")) # 当前cpu的时间 md5.update(user_data[\'session_key\'].encode("utf-8")) key = md5.hexdigest() cache.set(key,val) # redis数据库中保存 has_user = Wxuser.objects.filter(openid=user_data[\'openid\']).first() if not has_user: # 判断数据库中是否存在该用户 Wxuser.objects.create(openid=user_data[\'openid\']) return Response({ "status":0, "msg":"ok", "data":{"token":key} }) else: return Response({"status":2,"msg":"无效的code"})
1 因为部分功能需要用同意后才能使用。 2 wx.getSetting来判断该用户有没有对接口授权,我判断哪个接口,就必须给wx.getSetting传对应的scope值 - 一个scope值对应这个一个或多个接口 3 如果我们重wx.getSetting中发现scope值是false,标识没有授权,我们可以通过wx.authorize发起授权,对那个接口授权,就给wx.authorize传对应scope值就可以了。如果用用户同意授权,就可以直接使用对应的接口了。 4 但是scope.userInfo没有办法使用wx.authorize自动弹起弹框。必须要用户手动点击按钮唤起授权弹框。 代码格式: <button open-type="getUserInfo" bindgetuserinfo="user1">用户信息</button> 我们可以再响应函数的参数中获取用户信息。e.detail,这个和直接调用wx.getUserInfo获取的内容一样。
test3.wxml
<!--pages/test3/test3.wxml--> <button bindtap="click">跳转</button> <button bindtap="lu">录音</button> <button bindtap="user">用户信息</button> <button open-type="getUserInfo" bindgetuserinfo=\'user1\'>用户信息</button>
test3.js
// pages/test3/test3.js Page({ /** * 页面的初始数据 */ data: { }, click:function(){ wx.navigateBack({ delta:2 }) }, lu:function(){ wx.getSetting({ success(res) { console.log(res.authSetting) // 显示当前权限 if (!res.authSetting[\'scope.record\']) { // 获取用户录音权限 wx.authorize({ // 弹出弹框授权 scope: \'scope.record\', success() { // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() },fail(){ console.log(\'你没有权限\') } }) }else{ wx.startRecord() } } }) }, user:function(){ wx.getSetting({ success(res) { if (!res.authSetting[\'scope.userInfo\']) { // 获取用户信息权限 // wx.authorize({ // userInfo无法弹框,无法使用此方法 // scope: \'scope.userInfo\', // success() { // console.log(\'进来了\') // } // }) } else { console.log("已经授权") } } }) }, user1:function(e){ console.log(\'e\', e.detail) // 等同于wx.getUserInfo方法 wx.getSetting({ success(res) { if (res.authSetting[\'scope.userInfo\']) { // 获取用户信息权限 wx.getUserInfo({ success:(res) => { console.log(\'res\',res) } }) } } }) } })
bindgetuerinfo官方文档解释
scope中userInfo的官方文档解释
注意:权限一旦获得除非用户设置删除权限,清除缓存,或者删除小程序,否者权限一直纯在,调试中需要清楚缓存,才可多次测试
对应接口 | 描述 | |
---|---|---|
scope.userInfo | wx.getUserInfo | 用户信息 |
scope.userLocation | wx.getLocation, wx.chooseLocation | 地理位置 |
scope.userLocationBackground | wx.startLocationUpdateBackground | 后台定位 |
scope.address | wx.chooseAddress | 通讯地址 |
scope.invoiceTitle | wx.chooseInvoiceTitle | 发票抬头 |
scope.invoice | wx.chooseInvoice | 获取发票 |
scope.werun | wx.getWeRunData | 微信运动步数 |
scope.record | wx.startRecord | 录音功能 |
scope.writePhotosAlbum | wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum | 保存到相册 |
scope.camera | camera 组件 |