zoukankan      html  css  js  c++  java
  • 微信小程序开发4 登录与授权

    openid与unionid

    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 列表

    scope对应接口描述
    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 组件 摄像头
  • 相关阅读:
    Python装饰器
    Python导模块问题
    selenium定位元素提示‘元素不可见’问题解决方法
    Python导入模块Import和from+Import区别
    关于iframe切换的问题
    Python+selenium 模拟wap端页面操作
    使用Pytesseract+TesseractOCR识别图片的简单步骤
    通过cookie绕过验证码登录
    oo第三次作业——项目的问题与反思
    Java_第二次作业:项目构思与实现
  • 原文地址:https://www.cnblogs.com/ludingchao/p/12483250.html
Copyright © 2011-2022 走看看