微信小程序登录对接Django后端实现JWT方式验证登录详解


Posted in Javascript onJuly 29, 2019

先上效果图

微信小程序登录对接Django后端实现JWT方式验证登录详解

微信小程序登录对接Django后端实现JWT方式验证登录详解

点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料。

流程

1.使用微信小程序登录和获取用户信息Api接口
2.把Api获取的用户资料和code发送给django后端
3.通过微信接口把code换取成openid
4.后端将openid作为用户名和密码
5.后端通过JSON web token方式登录,把token和用户id传回小程序
6.小程序将token和用户id保存在storage中
下次请求需要验证用户身份的页面时,在header中加入token这个字段

微信小程序代码

获取用户信息的方法这里不展示,可以在微信小程序文档中看到

登录方法

login: function(event) {
 wx.login({
  success: res => {
  console.log(res)
  //请求后端换取openid的接口
  http.request({
   url: '/get-openid/',
   method: 'POST',
   data: {
   //将code传到后端
   jscode: res.code
   },
   success: res => {
   //获取到openid作为账号密码
   console.log(res)
   console.log(app.globalData.userInfo)
   http.request({
    url: '/wx-login/',
    method: 'POST',
    data: {
    openid: res.openid,
    session_key: res.session_key,
    nickname: app.globalData.userInfo.nickName,
    avatar_url: app.globalData.userInfo.avatarUrl,
    gender: app.globalData.userInfo.gender
    },
    //登录成功后返回token保存在storage中
    success: res => {
    console.log(res)
    //token存入storage
    wx.setStorageSync('jwt_token', res.token)
    wx.setStorageSync('user_id', res.user_id)
    this.reFreshUserProfile()
    //登录状态置为true
    this.setData({
     isLogin: true,
     hasUserInfo: true
    })
    app.globalData.isLogin = true
    }
   })

   }
  })
  }
 })
 }

注销方法

logout: function(res) {
 this.setData({
  isLogin:false,
  hasUserInfo:false
 })
 app.globalData.isLogin = false
 wx.removeStorageSync('jwt_token')
 wx.removeStorageSync('user_id')
 },

Django后端的实现

首先安装djangorestframework-jwt

这里不使用他默认的登录接口,如下所示

微信小程序登录对接Django后端实现JWT方式验证登录详解

它提供了手动签发token和解密token的功能,因此最好自己实现

手动签发token

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
 payload = jwt_payload_handler(user)
 token = jwt_encode_handler(payload)

手动解密token

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
 user_dict = jwt_decode_handler(token)
 user_id = user_dict['user_id']

后端换取openid

class OpenId:
 def __init__(self, jscode):
  self.url = 'https://api.weixin.qq.com/sns/jscode2session'
  self.app_id = env.str('APPID')
  self.app_secret = env.str('APPSECRET')
  self.jscode = jscode

 def get_openid(self):
  url = self.url + "?appid=" + self.app_id + "&secret=" + self.app_secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"
  res = requests.get(url)
  try:
   openid = res.json()['openid']
   session_key = res.json()['session_key']
  except KeyError:
   return 'fail'
  else:
   return openid, session_key

后端返回openid接口实现

这里只使用简单的FBV视图

注:前端传来的值无法从request.POST中接收到,只能使用如下方法

@require_http_methods(['POST'])
@csrf_exempt
def GetOpenIdView(request):
 data = json.loads(request.body)
 jscode = data['jscode']

 openid, session_key = OpenId(jscode).get_openid()
 return JsonResponse({
  'openid': openid,
  'session_key': session_key
 })

后端登录接口实现

如果不存在用户则自动创建
为了简单,用户名和密码都是openid

@require_http_methods(['POST'])
@csrf_exempt
def login_or_create_account(request):
 data = json.loads(request.body)
 print(data)
 openid = data['openid']
 nickname = data['nickname']
 avatar_url = data['avatar_url']
 gender = data['gender']

 try:
  user = User.objects.get(username=openid)
 except User.DoesNotExist:
  user = None

 if user:
  user = User.objects.get(username=openid)
 else:
  user = User.objects.create(
   username=openid,
   password=openid,
   nickname=nickname,
   avatar_url=avatar_url,
   gender=gender
  )

 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
 payload = jwt_payload_handler(user)
 token = jwt_encode_handler(payload)
 res = {
  'status': 'success',
  'nickname': user.nickname,
  'user_id': user.id,
  'token': token
 }
 return JsonResponse(res)

以上就是简单的微信小程序登录对接Django的思路,很多地方不严谨,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 篱式条件判断
Aug 22 Javascript
初学Javascript的一些总结
Nov 03 Javascript
JQuery与Ajax常用代码实现对比
Oct 03 Javascript
jMessageBox 基于jQuery的窗口插件
Dec 09 Javascript
jQuery中:button选择器用法实例
Jan 04 Javascript
jquery通过closest选择器修改上级元素的方法
Mar 17 Javascript
js 定义对象数组(结合)多维数组方法
Jul 27 Javascript
PHP捕捉异常中断的方法
Oct 24 Javascript
JavaScript注入漏洞的原理及防范(详解)
Dec 04 Javascript
JS解析后台返回的JSON格式数据实例
Aug 06 Javascript
Vue基于iview table展示图片实现点击放大
Aug 05 Javascript
vue组件vue-esign实现电子签名
Apr 21 Vue.js
JavaScript HTML DOM元素 节点操作汇总
Jul 29 #Javascript
vue.js 2.0实现简单分页效果
Jul 29 #Javascript
JavaScript如何获取一个元素的样式信息
Jul 29 #Javascript
教你搭建按需加载的Vue组件库(小结)
Jul 29 #Javascript
JavaScript 继承 封装 多态实现及原理详解
Jul 29 #Javascript
Vue2.0实现简单分页及跳转效果
Jul 29 #Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
Jul 29 #Javascript
You might like
国产动画《伍六七》原声大碟大卖,啊哈娱乐引领音乐赋能IP的新尝试
2020/03/08 国漫
PHP安全配置详细说明
2011/09/26 PHP
php一个找二层目录的小东东
2012/08/02 PHP
PHP编程函数安全篇
2013/01/08 PHP
PHP中使用localhost连接Mysql不成功的解决方法
2014/08/20 PHP
PHP实现动态柱状图改进版
2015/03/30 PHP
php求一个网段开始与结束IP地址的方法
2015/07/09 PHP
YII Framework框架教程之缓存用法详解
2016/03/14 PHP
PHP实现移除数组中为空或为某值元素的方法
2017/01/07 PHP
javascript XMLHttpRequest对象全面剖析
2010/04/24 Javascript
jQuery.Highcharts.js绘制柱状图饼状图曲线图
2015/03/14 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
js异步编程小技巧详解
2017/08/14 Javascript
JavaScript贪吃蛇小组件实例代码
2017/08/20 Javascript
vue使用axios时关于this的指向问题详解
2017/12/22 Javascript
聊聊JS动画库 Velocity.js的使用
2018/03/13 Javascript
vue todo-list组件发布到npm上的方法
2018/04/04 Javascript
vue中的provide/inject的学习使用
2018/05/09 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
vue路由组件按需加载的几种方法小结
2018/07/12 Javascript
vue.js中toast用法及使用toast弹框的实例代码
2018/08/27 Javascript
js实现前面自动补全位数的方法
2018/10/10 Javascript
如何在微信小程序中存setStorage
2019/12/13 Javascript
解决elementUI 切换tab后 el_table 固定列下方多了一条线问题
2020/07/19 Javascript
Python3读取UTF-8文件及统计文件行数的方法
2015/05/22 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
Pyinstaller打包Scrapy项目的实现步骤
2020/09/22 Python
python 爬虫如何实现百度翻译
2020/11/16 Python
CSS3中animation实现流光按钮效果
2020/12/21 HTML / CSS
用canvas画心电图的示例代码
2018/09/10 HTML / CSS
普天C++笔试题
2016/03/20 面试题
存储过程和sql语句的优缺点
2014/07/02 面试题
生产文员岗位职责
2014/04/05 职场文书
协议书怎么写
2014/04/21 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
事业单位岗位说明书
2015/10/08 职场文书