Django之开发微信小程序后端-会话管理篇③
文章目录
- 有状态服务
- 什么是状态
- HTP协议中的状态
- 有状态服()
- 4-3 小程序的状态管理
- 小程序Stronge存储cookies
- Session中间件
- 4-4 实现登录功能
- 用户体系的建立
- 定义数据库模型
- 生成数据库模型
- 前端从后端接口判断是否登录
- 登录时获取并存储cookie
- 后端获取前端传递的个人信息openid
- 查看session_user
- 4-5 完善用户个人信息
- 查看个人信息
- 4-6 复杂多变的用户状态管理
- 4-7 有状态的首页(登录查询个人的添加记录)
有状态服务
什么是状态
HTP协议中的状态
有状态服()
4-3 小程序的状态管理
小程序Stronge存储cookies
- 在utils中设置cookies.js
const key = 'cookie'function getSessionIDFromResponse(res){var cookie = res.header['Set-Cookie']console.log('get cookie from response: ', cookie)return cookie }function setCookieToStorage(cookie) {try {console.log(cookie)wx.setStorageSync(key, cookie)} catch (e) {console.log(e)} }function getCookieFromStorage() {var value = wx.getStorageSync(key)console.log(value)return value }module.exports = {setCookieToStorage: setCookieToStorage,getCookieFromStorage: getCookieFromStorage,getSessionIDFromResponse: getSessionIDFromResponse }
- 测试
Session中间件
4-4 实现登录功能
用户体系的建立
定义数据库模型
from django.db import models# Create your models here.
class User(models.Model):# open_idopen_id = models.CharField(max_length=64, unique=True)# 昵称nickname = models.CharField(max_length=256)# 关注的城市focus_cities = models.TextField(default='[]')# 关注的星座focus_constellations = models.TextField(default='[]')# 关注的股票focus_stocks = models.TextField(default='[]')
生成数据库模型
(venv) D:\Python_projects\backend-3-9>python manage.py makemigrations
Migrations for 'authorization':authorization\migrations\0001_initial.py- Create model User(venv) D:\Python_projects\backend-3-9>python manage.py migrate
Operations to perform:Apply all migrations: admin, auth, authorization, contenttypes, sessions
Running migrations:No migrations to apply.
如果是测试号需要去申请去微信社区申请
前端从后端接口判断是否登录
// pages/homepage/homepage.jsconst app = getApp()
const cookieUtil = require('../../utils/cookie.js')Page({/*** 页面的初始数据*/data: {},onReadCookies: function (){wx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/auth/test',success(res) {var cookie = cookieUtil.getSessionIDFromResponse(res)console.log(cookie)}})},// navigator跳转处理onNavigatorTap: function (event) {var that = thisvar cookie = cookieUtil.getCookieFromStorage()var header = {}header.Cookie = cookiewx.request({url: app.globalData.serverUrl + '/api/v1.0/auth/status',header: header,success: function (res) {var data = res.data.dataconsole.log(data)if (data.is_authorized == 1) {that.setData({isLogin: true})app.setAuthStatus(true)} else {that.setData({isLogin: false})app.setAuthStatus(false)wx.showToast({title: '请先授权登录',})}if (data.is_authorized == 1){// 获取由 data-type 标签传递过来的参数console.log(event.currentTarget.dataset.type)var navigatorType = event.currentTarget.dataset.typeif (navigatorType == 'focusCity') {navigatorType = 'city'} else if (navigatorType == 'focusStock') {navigatorType = 'stock'} else {navigatorType = 'constellation'}var url = '../picker/picker?type=' + navigatorTypeconsole.log('navigateTo url: ' + url)wx.navigateTo({url: '../picker/picker?type=' + navigatorType,})}}})},
登录时获取并存储cookie
authorize: function () {console.log('authorize')var that = this// 登陆并获取cookiewx.login({success: function (res) {console.log(res)var code = res.codevar appId = app.globalData.appIdvar nickname = app.globalData.userInfo.nickName// 请求后台wx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/auth/authorize',method: 'POST',data: {code: code,appId: appId,nickname: nickname },header: {'content-type': 'application/json' // 默认值},success(res) {wx.showToast({title: '授权成功',})// 保存cookievar cookie = cookieUtil.getSessionIDFromResponse(res)cookieUtil.setCookieToStorage(cookie)that.setData({isLogin: true,userInfo: app.globalData.userInfo,hasUserInfo: true})app.setAuthStatus(true)}})}})},
后端获取前端传递的个人信息openid
def __authorize_by_code(request):'''使用wx.login的到的临时code到微信提供的code2session接口授权post_data = {'encryptedData': 'xxxx','appId': 'xxx','sessionKey': 'xxx','iv': 'xxx'}'''response = {}post_data = request.body.decode('utf-8')post_data = json.loads(post_data)app_id = post_data.get('appId').strip()nickname = post_data.get('nickname').strip()code = post_data.get('code').strip()print("code", code)print("app_id", app_id)if not (app_id and code):response['result_code'] = ReturnCode.BROKEN_AUTHORIZED_DATAresponse['message'] = 'authorized failed. need entire authorization data.'return JsonResponse(response, safe=False)try:data = c2s(app_id, code)except Exception as e:print(e)response['result_code'] = ReturnCode.FAILEDresponse['message'] = 'authorized failed.'return JsonResponse(response, safe=False)open_id = data.get('openid')if not open_id:response['result_code'] = ReturnCode.FAILEDresponse['message'] = 'authorization error.'return JsonResponse(response, safe=False)request.session['open_id'] = open_idrequest.session['is_authorized'] = Trueprint("open_id", open_id)# User.objects.get(open_id=open_id) # 不要用get,用get查询如果结果数量 !=1 就会抛异常# 如果用户不存在,则新建用户if not User.objects.filter(open_id=open_id):new_user = User(open_id=open_id, nickname=nickname)new_user.save()message = 'user authorize successfully.'response = wrap_json_response(data={}, code=ReturnCode.SUCCESS, message=message)return JsonResponse(response, safe=False)
查看session_user
(venv) D:\Python_projects\backend-3-9>python manage.py dbshell
SQLite version 3.26.0 2018-12-01 12:34:55
Enter ".help" for usage hints.
sqlite> select * from authorization_user;
2|oXSML0ZH05BItFTFILfgCG6cTxik|咚咚呛!|[{"province": "\u5e7f\u4e1c\u7701", "area": "\u5357\u5c71\u533a", "city": "\u6df1\u5733\u5e02"}, {"province": "\u5e7f\u4e1c\u7701", "area": "\u76d0\u7530\u533a", "city": "\u6df1\u5733\u5e02"}]|["\u767d\u7f8a\u5ea7", "\u72ee\u5b50\u5ea7", "\u5904\u5973\u5ea7", "\u5c04\u624b\u5ea7"]|[{"name": "\u4e16\u7eaa\u661f\u6e90", "fullInfo": "\u6df1\u4ea4\u6240-\u4e16\u7eaa\u661f\u6e90(000005)", "market": "sz", "code": "000005"}, {"code": "000006", "name": "\u6df1\u632f\u4e1a\uff21", "fullInfo": "\u6df1\u4ea4\u6240-\u6df1\u632f\u4e1a\uff21(000006)", "market": "sz"}]
3|oRRtbv1RU2rC3zx2gTjoThOlLhas||[]|[]|[]
sqlite>
4-5 完善用户个人信息
查看个人信息
class UserView(View, CommonResponseMixin):# 关注的城市、股票和星座def get(self, request):if not already_authorized(request):response = self.wrap_json_response(code=ReturnCode.UNAUTHORIZED)return JsonResponse(response, safe=False)open_id = request.session.get('open_id')user = User.objects.get(open_id=open_id)data = {}data['open_id'] = user.open_iddata['focus'] = {}print(user.focus_cities)data['focus']['city'] = json.loads(user.focus_cities)data['focus']['constellation'] = json.loads(user.focus_constellations)data['focus']['stock'] = json.loads(user.focus_stocks)print('data: ', data)response = CommonResponseMixin.wrap_json_response(code=ReturnCode.SUCCESS, data=data)return JsonResponse(response, safe=False)def post(self, request):if not already_authorized(request):response = self.wrap_json_response(code=ReturnCode.UNAUTHORIZED)return JsonResponse(response, safe=False)open_id = request.session.get('open_id')user = User.objects.get(open_id=open_id)# got str objectreceived_body = request.body.decode('utf-8')received_body = eval(received_body)cities = received_body.get('city')stocks = received_body.get('stock')constellations = received_body.get('constellation')if cities == None: cities = []if stocks == None: stocks = []if constellations == None: constellations = []user.focus_cities = json.dumps(cities)user.focus_constellations = json.dumps(constellations)user.focus_stocks = json.dumps(stocks)user.save()message = 'modify user info success.'response = CommonResponseMixin.wrap_json_response(code=ReturnCode.SUCCESS, message=message)return JsonResponse(response, safe=False)
4-6 复杂多变的用户状态管理
pages/picker.js
const cookieUtil = require('../../utils/cookie.js')
const szStock = require('../../resources/data/stock/sz-100.js')
const shStock = require('../../resources/data/stock/sh-100.js')var allStockData = []
Array.prototype.push.apply(allStockData, szStock.data)
Array.prototype.push.apply(allStockData, shStock.data)const app = getApp()Page({data: {isConstellPicker: false,isStockPicker: false,isCityPicker: false,personal: {constellation: [],city: [],stock: []},allPickerData: {allConstellation: ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座'],allStock: []}},onLoad: function(options) {var that = this// 1. 判断类型console.log(options.type)this.setData({isConstellPicker: false,isStockPicker: false,isCityPicker: false,})if (options.type == 'city') {this.setData({isCityPicker: true,})} else if (options.type == 'constellation') {this.setData({isConstellPicker: true,})} else {this.setData({isStockPicker: true,})}var newPickerData = this.data.allPickerDatanewPickerData.allStock = allStockDatathis.setData({allPickerData: newPickerData})// 2. 加载数据var header = {}var cookie = cookieUtil.getCookieFromStorage()header.Cookie = cookiewx.request({url: app.globalData.serverUrl + '/api/v1.0/auth/user',method: 'GET',header: header,success(res) {console.log(res)that.setData({personal: res.data.data.focus})}})},bindConstellationPickerChange: function(e) {console.log('constellPicker发送选择改变,携带值为', e.detail.value)var newItem = this.data.allPickerData.allConstellation[e.detail.value]var newData = this.data.personal.constellation// 去重if (newData.indexOf(newItem) > -1)returnnewData.push(newItem)var newPersonalData = this.data.personalnewPersonalData.constellation = newDatathis.setData({personal: newPersonalData})},bindStockPickerChange: function(e) {var newItem = this.data.allPickerData.allStock[e.detail.value]var newData = this.data.personal.stock// 去重for (var i = 0; i < newData.length; i++) {if (newData[i].name == newItem.name && newData[i].code == newItem.code && newData[i].market == newItem.market) {console.log('already exists.')return}}newData.push(newItem)var newPersonalData = this.data.personalnewPersonalData.stock = newDatathis.setData({personal: newPersonalData})},bindRegionPickerChange: function(e) {console.log('cityPicker发送选择改变,携带值为', e.detail.value)var pickerValue = e.detail.valuevar newItem = {province: pickerValue[0],city: pickerValue[1],area: pickerValue[2],}var newData = this.data.personal.city// 去重for (var i = 0; i < newData.length; i++) {if (newData[i].province == newItem.province && newData[i].city == newItem.city && newData[i].area == newItem.area) {console.log('already exists.')return}}newData.push(newItem)var newPersonalData = this.data.personalnewPersonalData.city = newDatathis.setData({personal: newPersonalData})},// 删除列表元素deleteItem: function(e) {var that = thisvar deleteType = e.currentTarget.dataset.typevar index = e.currentTarget.dataset.indexconsole.log('delete type: ' + deleteType)console.log('delete index: ' + index)var personalData = this.data.personalwx.showModal({content: "确认删除此项吗?",showCancel: true,success: function(res) {console.log(res)if (res.confirm) {if (deleteType == 'constellation') {personalData.constellation.splice(index, 1)} else if (deleteType == 'stock') {personalData.stock.splice(index, 1)} else {personalData.city.splice(index, 1)}that.setData({personal: personalData})that.onSave(false)}}})},// 保存后台onSave: function(isShowModal=true) {var that = thisvar header = {}var cookie = cookieUtil.getCookieFromStorage()header.Cookie = cookiewx.request({url: app.globalData.serverUrl + '/api/v1.0/auth/user',method: 'POST',data: {city: that.data.personal.city,stock: that.data.personal.stock,constellation: that.data.personal.constellation},header: header,success(res) {console.log(res)if (isShowModal){wx.showToast({title: '保存成功',})}}})
}
});
class UserView(View, CommonResponseMixin):# 关注的城市、股票和星座def get(self, request):if not already_authorized(request):response = self.wrap_json_response(code=ReturnCode.UNAUTHORIZED)return JsonResponse(response, safe=False)open_id = request.session.get('open_id')user = User.objects.get(open_id=open_id)data = {}data['open_id'] = user.open_iddata['focus'] = {}print(user.focus_cities)data['focus']['city'] = json.loads(user.focus_cities)data['focus']['constellation'] = json.loads(user.focus_constellations)data['focus']['stock'] = json.loads(user.focus_stocks)print('data: ', data)response = CommonResponseMixin.wrap_json_response(code=ReturnCode.SUCCESS, data=data)return JsonResponse(response, safe=False)def post(self, request):if not already_authorized(request):response = self.wrap_json_response(code=ReturnCode.UNAUTHORIZED)return JsonResponse(response, safe=False)open_id = request.session.get('open_id')user = User.objects.get(open_id=open_id)# got str objectreceived_body = request.body.decode('utf-8')received_body = eval(received_body)cities = received_body.get('city')stocks = received_body.get('stock')constellations = received_body.get('constellation')if cities == None: cities = []if stocks == None: stocks = []if constellations == None: constellations = []user.focus_cities = json.dumps(cities)user.focus_constellations = json.dumps(constellations)user.focus_stocks = json.dumps(stocks)user.save()message = 'modify user info success.'response = CommonResponseMixin.wrap_json_response(code=ReturnCode.SUCCESS, message=message)return JsonResponse(response, safe=False)
4-7 有状态的首页(登录查询个人的添加记录)
首先判断是否登录,登录就从数据库中查询出数据,返回给前端展示,没有登陆提示未登录
# 星座运势
def constellation(request):data = []if already_authorized(request):user = get_user(request)print('星座:', user.focus_constellations)constellations = json.loads(user.focus_constellations)else:constellations = all_constellationsfor c in constellations:result = thirdparty.juhe.constellation(c)data.append(result)response = CommonResponseMixin.wrap_json_response(data=data, code=ReturnCode.SUCCESS)return JsonResponse(response, safe=False)# 股票
def stock(request):data = []stocks = []if already_authorized(request):print("已登录")user = get_user(request)stocks = json.loads(user.focus_stocks)else:print("未登录")stocks = popular_stocksfor stock in stocks:result = thirdparty.juhe.stock(stock['market'], stock['code'])data.append(result)response = CommonResponseMixin.wrap_json_response(data=data, code=ReturnCode.SUCCESS)return JsonResponse(response, safe=False)# 笑话
def joke(request):global joke_cacheif not joke_cache:joke_cache = json.load(open(os.path.join(settings.BASE_DIR, 'jokes.json'), 'r'))# 读缓存all_jokes = joke_cachelimit = 10sample_jokes = random.sample(all_jokes, limit)response = CommonResponseMixin.wrap_json_response(data=sample_jokes, code=ReturnCode.SUCCESS)return JsonResponse(response, safe=False)
首页index.js
//index.js
//获取应用实例
const app = getApp()
const cookieUtil = require('../../utils/cookie.js')Page({data: {isAuthorized: false,constellationData: null,stockData: null,weatherData: null},//事件处理函数bindViewTap: function() {wx.navigateTo({url: '../logs/logs'})},updateData: function() {wx.showLoading({title: '加载中',})var that = thisvar cookie = cookieUtil.getCookieFromStorage()var header = {}header.Cookie = cookiewx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/service/weather',header: header,success: function(res){that.setData({weatherData: res.data.data})wx.hideLoading()}})wx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/service/constellation',header: header,success: function (res) {that.setData({constellationData: res.data.data})wx.hideLoading()}})wx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/service/stock',header: header,success: function (res) {that.setData({stockData: res.data.data})wx.hideLoading()}})},onPullDownRefresh: function() {var that = thisvar cookie = cookieUtil.getCookieFromStorage()var header = {}header.Cookie = cookiewx.request({url: app.globalData.serverUrl + app.globalData.apiVersion + '/auth/status',header: header,success: function(res){var data = res.data.dataif (data.is_authorized == 1){that.setData({isAuthorized: true})that.updateData()}else{that.setData({isAuthorized: false})wx.showToast({title: '请先授权登录',})}}})},onLoad: function() {if (app.globalData.userInfo) {this.setData({userInfo: app.globalData.userInfo,hasUserInfo: true})} else if (this.data.canIUse) {// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回// 所以此处加入 callback 以防止这种情况app.userInfoReadyCallback = res => {this.setData({userInfo: res.userInfo,hasUserInfo: true})}} else {// 在没有 open-type=getUserInfo 版本的兼容处理wx.getUserInfo({success: res => {app.globalData.userInfo = res.userInfothis.setData({userInfo: res.userInfo,hasUserInfo: true})}})}},getUserInfo: function(e) {console.log(e)app.globalData.userInfo = e.detail.userInfothis.setData({userInfo: e.detail.userInfo,hasUserInfo: true})}
})
Django之开发微信小程序后端-会话管理篇③相关推荐
- Django之开发微信小程序后端-微信小程序篇①
开始上班~~~ 文章目录 第1章.课程介绍 三类技术要点 小程序技术要点 Django技术要点 服务端技术要点 第2章 小程序开发入门 2-2 小程序开发的准备工作 小程序开发规范 2-3 项目工程的 ...
- 用 Django 开发微信小程序后端实现用户登录
本文将介绍采用 Django 开发微信小程序后端,通过将用户模块进行重构,并采用JWT来进行用户认证,来解决以下问题: 微信小程序不支持 Cookie,因此不能采用 Django 默认的 Sessio ...
- 关于开发微信小程序后端linux使用xampp配置https
关于开发微信小程序后端linux使用xampp配置https 背景 由于最近开发微信小程序,前后端交互需要使用https协议,故需要配置https服务 服务器环境 服务器系统 ubuntu 环境 xa ...
- python微信小程序后端开发_使用django开发微信小程序后端
tips: 本文面向的对象是已经会使用django开发web后端的人员 微信小程序后端与普通web的区别 微信小程序的后端开发和普通的restful API 大致上相同,只不过要注意以下几点限制 必须 ...
- 从0到一开发微信小程序(6)—小程序常用API
文章目录 其他相关文章 1.小程序API 1.1.路由 1.1.1.navigateTo(保留当前页面,跳转到应用内的某个页面,可以带参数) 1.1.2.redirectTo(关闭当前页面,跳转到应用 ...
- 基于腾讯云开发微信小程序(新闻发布及共享平台)上
基于腾讯云开发微信小程序(新闻发布及共享平台)上 文章目录 传统的微信小程序开发 一.云开发是什么? 二.使用步骤 1.创建云环境 2.云数据库的创建 3.云储存 4.云函数 总结 传统的小程序开发 ...
- python开发微信小程序-微信小程序开发:python+sanic 实现小程序登录注册
开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...
- python开发微信小程序-Python 开发者的微信小程序开发实践
导读 在知乎上,有人提问"如何使用 Python 开发微信小程序". 其实微信小程序作为一个前端的机制,Python 并不能插上边.只不过可以作为后端接口为微信小程序提供数据服务而 ...
- 使用牛刀云开发微信小程序(问题集锦)
前不久,起步科技正式推出牛刀云1.0,我想这也应该是许多WeX5的忠诚追随者(我也算是其中之一吧)期望的结果了.使用牛刀云开发微信小程序,能够实现使用类似于WeX5的所见即所得组件积木搭建方式构建前端 ...
最新文章
- 如何使用vs来运行box2d中Testbed的案例
- 别人总结的批处理技巧
- WebAssembly:面向Web的通用二进制和文本格式
- python读取配置文件
- 20g的ubuntu虚拟机socket问题记录:只能单向通信(只能发出不能接收)
- Spring-级联赋值
- scala教程之:可见性规则
- QT+VTK 对接使用
- IRP和IO_STACK_LOCATION
- 罗永浩欲直播带货,京东说可以帮忙联系
- 生产者消费者代码_生产者消费者模型:Kotlin 多线程读写文件实例
- 不能使用泛型的形参创建对象_数据类型之----泛型
- python编程快速上手实例_Python编程快速上手——疯狂填词程序实现方法分析
- 使用selenium下载百度图片
- ddr4单颗粒最大_国产DDR4内存颗粒!南亚DDR4颗粒超频测试
- Visual SourceSafe如何支持并行开发
- Hadoop分布式集群的安装与部署实训总结报告
- 微信公众号 - H5 网页接入微信支付(JSAPI)
- vue引入海康监控web无插件开发的问题
- MongoDB安装教程(Win10Linux)
热门文章
- 将Chrome浏览器网页背景改成豆绿色
- Java 矩阵主对角线所有数字之和
- 我设计开发的第一个产品发布了,微信小程序“集美装修效果图“
- HUAWEI Sound Joy首发体验,独具一格的华为音质究竟如何呢?
- CorelDRAWX4的VBA插件开发(二十四)复合选框组件与联合命名面板
- 谈谈我的技术专家之路
- Python爬虫:运用多线程、IP代理模块爬取百度图片上小姐姐的图片
- OrangePi PC 玩Linux主线内核踩坑之旅(二)之制作镜像后的查遗补缺
- 第三届阿里巴巴全球数学竞赛落下帷幕,这届90后属实优秀!北大恐成最大赢家!
- 一个月裂变50多万人?商城引流模式玩法——分享购