文章目录

  • 有状态服务
    • 什么是状态
    • 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之开发微信小程序后端-会话管理篇③相关推荐

  1. Django之开发微信小程序后端-微信小程序篇①

    开始上班~~~ 文章目录 第1章.课程介绍 三类技术要点 小程序技术要点 Django技术要点 服务端技术要点 第2章 小程序开发入门 2-2 小程序开发的准备工作 小程序开发规范 2-3 项目工程的 ...

  2. 用 Django 开发微信小程序后端实现用户登录

    本文将介绍采用 Django 开发微信小程序后端,通过将用户模块进行重构,并采用JWT来进行用户认证,来解决以下问题: 微信小程序不支持 Cookie,因此不能采用 Django 默认的 Sessio ...

  3. 关于开发微信小程序后端linux使用xampp配置https

    关于开发微信小程序后端linux使用xampp配置https 背景 由于最近开发微信小程序,前后端交互需要使用https协议,故需要配置https服务 服务器环境 服务器系统 ubuntu 环境 xa ...

  4. python微信小程序后端开发_使用django开发微信小程序后端

    tips: 本文面向的对象是已经会使用django开发web后端的人员 微信小程序后端与普通web的区别 微信小程序的后端开发和普通的restful API 大致上相同,只不过要注意以下几点限制 必须 ...

  5. 从0到一开发微信小程序(6)—小程序常用API

    文章目录 其他相关文章 1.小程序API 1.1.路由 1.1.1.navigateTo(保留当前页面,跳转到应用内的某个页面,可以带参数) 1.1.2.redirectTo(关闭当前页面,跳转到应用 ...

  6. 基于腾讯云开发微信小程序(新闻发布及共享平台)上

    基于腾讯云开发微信小程序(新闻发布及共享平台)上 文章目录 传统的微信小程序开发 一.云开发是什么? 二.使用步骤 1.创建云环境 2.云数据库的创建 3.云储存 4.云函数 总结 传统的小程序开发 ...

  7. python开发微信小程序-微信小程序开发:python+sanic 实现小程序登录注册

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...

  8. python开发微信小程序-Python 开发者的微信小程序开发实践

    导读 在知乎上,有人提问"如何使用 Python 开发微信小程序". 其实微信小程序作为一个前端的机制,Python 并不能插上边.只不过可以作为后端接口为微信小程序提供数据服务而 ...

  9. 使用牛刀云开发微信小程序(问题集锦)

    前不久,起步科技正式推出牛刀云1.0,我想这也应该是许多WeX5的忠诚追随者(我也算是其中之一吧)期望的结果了.使用牛刀云开发微信小程序,能够实现使用类似于WeX5的所见即所得组件积木搭建方式构建前端 ...

最新文章

  1. 如何使用vs来运行box2d中Testbed的案例
  2. 别人总结的批处理技巧
  3. WebAssembly:面向Web的通用二进制和文本格式
  4. python读取配置文件
  5. 20g的ubuntu虚拟机socket问题记录:只能单向通信(只能发出不能接收)
  6. Spring-级联赋值
  7. scala教程之:可见性规则
  8. QT+VTK 对接使用
  9. IRP和IO_STACK_LOCATION
  10. 罗永浩欲直播带货,京东说可以帮忙联系
  11. 生产者消费者代码_生产者消费者模型:Kotlin 多线程读写文件实例
  12. 不能使用泛型的形参创建对象_数据类型之----泛型
  13. python编程快速上手实例_Python编程快速上手——疯狂填词程序实现方法分析
  14. 使用selenium下载百度图片
  15. ddr4单颗粒最大_国产DDR4内存颗粒!南亚DDR4颗粒超频测试
  16. Visual SourceSafe如何支持并行开发
  17. Hadoop分布式集群的安装与部署实训总结报告
  18. 微信公众号 - H5 网页接入微信支付(JSAPI)
  19. vue引入海康监控web无插件开发的问题
  20. MongoDB安装教程(Win10Linux)

热门文章

  1. 将Chrome浏览器网页背景改成豆绿色
  2. Java 矩阵主对角线所有数字之和
  3. 我设计开发的第一个产品发布了,微信小程序“集美装修效果图“
  4. HUAWEI Sound Joy首发体验,独具一格的华为音质究竟如何呢?
  5. CorelDRAWX4的VBA插件开发(二十四)复合选框组件与联合命名面板
  6. 谈谈我的技术专家之路
  7. Python爬虫:运用多线程、IP代理模块爬取百度图片上小姐姐的图片
  8. OrangePi PC 玩Linux主线内核踩坑之旅(二)之制作镜像后的查遗补缺
  9. 第三届阿里巴巴全球数学竞赛落下帷幕,这届90后属实优秀!北大恐成最大赢家!
  10. 一个月裂变50多万人?商城引流模式玩法——分享购