小程序登录、授权
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)
}
})
二、小程序的登入
1、搜微信小程序登录 文档



2、小程序登录 流程图



3、openid与unionid
openid:是用单个微信应用 表示用户的唯一标识。亚洲:饼哥小程序上openid :123,那该用户在张成的小程序上他的opendid不是123,是其他任意一个值。
上面的意思:同一用户在不同应用上的openid不同,但是在同一应用上唯一。
场景: 假设你们公司有2个小程序。但是你们老板想把用户做统一处理。比如新用户登入任意一个小程序,就发送礼包。但是只要在一个小程序上领过了,就不能再在另一个上面领取。
unionnid:一个用户在多个小程序有唯一的标识
4、小程序登录 步骤
1 小程序端执行wx.login()获取code


2 将1中的code发送到后端,并拿回token


后端
建文件

配置路由
视图类

小程序结果:

后台结果

3、后端调用auth.code2Session这个接口,后台就能得到小程序的 openid和session_key,并把openid存入数据库

openid 只能给一个APPID使用

把openid 存进缓存数据库中,需要redis配置

views文件夹中的user
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): # 接收从小程序发过来request中的code def post(self,request): param = request.data if not param.get("code"): return Response({"status":1,"msg":"缺少参数"}) else: code = param.get("code") # 调用wx_login文件中 get_login_info方法 user_data = wx_login.get_login_info(code) if user_data: print(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,86400) # 把字符串key 和val 存进缓存数据库里. 86400有效期时间 # 获取 微信用户对象 has_user = Wxuser.objects.filter(openid=user_data['openid']).first() if not has_user: # 把openid存如数据库,因为它是用户的唯一标识 Wxuser.objects.create(openid=user_data['openid']) return Response({ "status":0, "msg":"ok", "data":{"token":key} }) else: return Response({"status":2,"msg":"无效的code"})
models

3 以上代码实现了:自定义登入状态,我们生成一个key与openid和session_key相绑定。把key返回到小程序中
4 小程序端保存,然后下次请求需要登入的接口的时候,把key带上。
三、小程序授权
去看 开发文档
1 因为部分功能需要用同意后才能使用。
2 wx.getSetting来判断该用户有没有对接口授权,判断哪个接口,就必须给wx.getSetting传对应的scope值
一个scope值对应这个一个或多个接口
3 如果从wx.getSetting中发现scope值是false,表示a没有授权,我们可以通过wx.authorize发起授权,对那个接口授权,就给wx.authorize传对应scope值就可以了。如果用用户同意授权,就可以直接使用对应的接口了。
4 但是scope.userInfo没有办法使用wx.authorize自动弹起弹框。必须要用户手动点击按钮唤起授权弹框。
代码格式:
<button open-type="getUserInfo" bindgetuserinfo="user1">用户信息</button>
我们可以再响应函数的参数中获取用户信息。e.detail,这个和直接调用wx.getUserInfo获取的内容一样。

案例:
1、

2

3
// pages/test3/test3.js Page({ /*页面的初始数据*/ data: { }, click:function() { wx.navigateBack({ delta:2 }) }, lu:function(){ wx.getSetting({//查是否授权 success(res) {//结果 if (!res.authSetting['scope.record']) {//scope相当于key 。 record(录音) 是值 wx.authorize({// 表示授权 scope: 'scope.record', success () { // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() //用户 不同意 就进行fail回调。再点击也不会弹出授权框了 },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']) {// r如果授权了 wx.getUserInfo({//查用户的信息 success: (res) => { console.log("res",res) }, }) } } }) } })
结果:如下图

看开发文档

开放数据校验与解密




总结:
后端,如何解析wx.getUserInfor中的用户信息。
1 我们用encryptedData和iv,进行解密,必须要用到session_key,所以用必须是登入状态。
2 但是session_key是有有效期。而且session_key的有效期,不是一个固定值,他是通过用户行为来决定,session_key的有效期时间。
3 但是我们可以通过wx.checkSession来判断有没有过期。
4 保证session_key没有过期的情况下。我们将iv,encryptedData,token(登入凭证)发送到后端.
5 后端使用官方提供的sdk,进行解密。
6 解密成功以后保存到数据,数据库的字符集一定要是utf8mb4,才能保存表情包
看开发文档

总结的 案例 :
1、
//app.js App({ /* 当小程序初始话完成,会触发onlaunch(全局只触发一次)*/ onLaunch: function () { // 登录 this.my_login() //this 就是当前app对象 }, my_login: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/" } })
2、
// pages/test3/test3.js const app = getApp() //导入app.js Page({ /*页面的初始数据 */ data: { }, click:function() { wx.navigateBack({ delta:2 }) }, user1:function (e) { wx.getSetting({//检查是否授权 success(res) {//结果 if (res.authSetting['scope.userInfo']) {//如果授权了 wx.checkSession({ success () {//session_key 未过期,并且在本生命周期一直有效 wx.getUserInfo({//获取信息 success: (res) => { console.log("res",res)//这个res里面就是用户信息 //在session_key没有过期的情况下,将iv、数据发送后端 wx.request({ //这里是发送iv,encryptedData url: app.globalData.baseurl+"getinfo/", data:{ iv:res.iv, encryptedData:res.encryptedData, token: wx.getStorageSync('token') }, method:"POST", success: (e) => { console.log("后台返回的数据",e) } }) }, }) }, fail () { // session_key 已经失效,需要重新执行登录流程 app.my_login() wx.getUserInfo({ success: (res) => { console.log("res",res)//这个res里面就是用户信息 ////这里是发送iv,encryptedData,还没写 wx.request({ url: 'url', }) }, }) } })
后端
1、

2、
如官方的sdk没有Crypto包用下面的方法解决:
pip install pycryptodome

3、

4、
uesr文件
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 from app01.wx import WXBizDataCrypt from app01.my_ser import wx_user_ser class Info(APIView): def post(self,request): param = request.data if param.get('iv') and param.get('token') and param.get('encryptedData'): session_key_openid = cache.get(param.get("token")) if session_key_openid: session_key,openid = session_key_openid .split("&") #解密 user_info = WXBizDataCrypt.WXBizDataCrypt.get_info(session_key,param.get('encryptedData'),param.get('iv')) save_data = { "name":user_info['nickName'], "avatar":user_info['avatarUrl'], "language":user_info['language'], "province":user_info['province'], "city":user_info['city'], "country":user_info['country'], } Wxuser.objects.filter(openid=openid).update(**save_data) user1 = Wxuser.objects.filter(openid=openid).first() user = wx_user_ser(instance=user1,many=False).data return Response({ "status":0, "msg":"ok", "data":user }) else: return Response({"code": 2, "msg": "无效的token"}) else: return Response({"code":1,"msg":"缺少参数"})
注意:弹框只弹一次,要想再弹,就先


4、wx.authorize 表示授权,但是不能给 scope.userInfo授权
解决:主动手动授权
01、看开发文档

02、看上面的图2 3
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 组件 | 摄像头 |
四、如何添加 django server


Name 随便

。

浙公网安备 33010602011771号