微信小程序开发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 组件 摄像头

猜你喜欢

转载自www.cnblogs.com/ludingchao/p/12483250.html
今日推荐