微信小程序之登录连接django,以及用户的信息授权认证

小结:

1 如何自定义组件
	- 组件和页面一样,也是由四个文件组成,所以我们自定义组件的时候,模拟pages文件夹,把所有的所有的组件都放在一个文件夹中,每个组件又由一个文件夹包裹,方便管理,在对应目录右击,选择新建组件
	- 如果页面中要使用我们定义好的组件,必须现在对应页面的json文件中进行引用:代码如下
	{
      "usingComponents": {
        "com" : "/componentes/com/com" //形式 :组件名:组件路径
            }
	}
	在该页面的wxml文件中,就可以直接使用:
	<com name = "{{name1}}" bind:jia1 ="jia"></com>
	-页面向组件传值:要先在组件的js文件中的properties定义属性,在页面中就可以对这个组件的属性进行赋值了。
	-组件向页面传递事件:组件要先捕获事件,然后事件的响应函数里面用triggerEvent来把事件抛出来,然后页面捕获,组件抛出的事件。
	
2 小程序路由跳转js版
	- wx.switchTab 只能跳转到tabbar页面 ,并关闭所有非tabbar页面,而且路由不能传值
	- wx.reLaunch 关闭所有的页面,并打开你要跳转的页面.路由是可以携带参数
	- wx.redirectTO 关闭当前的页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面,路由可以携带参数
	- wx.navigateTo 保留当前的页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面,路由也可以携带参数。如果使用他,就会出现回退按钮,并且也可以用wx.navigateBack来进行返回
	- wx.navigateBack 里面有delta参数,他是用来表示回退多少个页面。

3 wx.request 相当于发送ajax请求
wx.request({
    url: //请求路径
    data:{} //请求发送的数据
    header:{} //请求头
    methond: "" //请求方法
    success(res){
        console.log(res.data)
    }
    
})

小程序的登录流程图

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带上。

小程序连入django,小程序的app.js

//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)
          }
        })
      }
    })

  /**可以在全局使用 */
  globalData: {
    userInfo: null,
    baseurl: "http://127.0.0.1:8000/"

  }
})

django的settings

#设置django—redis缓存 需要你下载插件pip install django-redis
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
             "PASSWORD": "Admin123",
        },
    },
}

# 配置数据库
import pymysql
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'wxxcx',
        'USER':'root',
        'PASSWORD':'123456',
        'HOST':'127.0.0.1',
        'PORT': 3306,
        #'OPTIONS': {'charset': 'utf8mb4'},
    }
}

urls主路由

from django.conf.urls import url
from django.contrib import admin
from app01.views import test, user

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'test/', test.Test.as_view()),
    url(r'login/', user.Login.as_view())
]

自定义有关小程序的settings

AppId="xxxx" # 写你自己的小程序的id

AppSecret="xxxx" # 写你自己的小程序的秘钥

code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"

自定义获取小程序的登录wx_login

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的字典
    if json_response.get("session_key"):
        return json_response
    else:
        return False

得到openid以及加密并返回小程序token

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'))
                md5.update(user_data['session_key'].encode('utf-8'))
                key = md5.hexdigest()
                cache.set(key, val)
                has_user = Wxuser.objects.filter(openid=user_data['openid']).first()
                if not has_user:
                    Wxuser.objects.create(openid=user_data['openid'])
                Wxuser.objects.update()
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'data': {'token':key}
                })
            else:
                return Response({'status':2, 'msg': "无效的code"})

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

小程序授权

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获取的内容一样。



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 组件 摄像头

小程序的页面的js文件

// pages/test3/test3.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  click:function() {
    wx.navigateBack({
     delta:2
    })
  },
  luyin:function(){

    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.record']) { //录音的scope
          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({
            scope: 'scope.userInfo',
            success() {
             console.log('进来了')
            }
          })
        } else {
          console.log('已经授权')
        }
      }
    })

  },

  user1:function(e){
    console.log("e",e.detail)

    wx.getSetting({
      success(res) {
        if (res.authSetting['scope.userInfo']) { //用户信息的scope
          wx.getUserInfo({
            success: (res) =>{
              console.log("res", res)

            }
          })
        } 
      }
    })
  },
})

小程序页面的wxml文件

<!--pages/test3/test3.wxml-->
<text>pages/test3/test3.wxml</text>
<button bindtap="click">tiao</button>
<button bindtap="luyin">录音</button>

<button open-type="getUserInfo" 
bindgetuserinfo="user1">用户信息</button>
<!--要想要将用户的信息授权时弹框,必须用一个button按钮,且open-type必须为getUserInfo以及给事件为bindgetuserinfo-->

原文地址:https://www.cnblogs.com/yafeng666/p/12482843.html