微信小程序登录对接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 设计模式 推荐
Oct 28 Javascript
用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
Jun 19 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
Sep 21 Javascript
火狐下table中创建form导致两个table之间出现空白
Sep 02 Javascript
jQuery实现跨域
Feb 03 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
Mar 24 Javascript
Angularjs cookie 操作实例详解
Sep 27 Javascript
详解JavaScript事件循环机制
Sep 07 Javascript
vue项目中使用eslint+prettier规范与检查代码的方法
Jan 16 Javascript
小程序Scroll-view上拉滚动刷新数据
Jun 21 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
Nov 01 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 Javascript
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
如何使用PHP获取网络上文件
2006/10/09 PHP
ThinkPHP表单自动提交验证实例教程
2014/07/18 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
实例分析PHP将字符串转换成数字的方法
2019/01/27 PHP
在线编辑器的实现原理(兼容IE和FireFox)
2007/03/09 Javascript
SWFObject Flash js调用类
2008/07/08 Javascript
JavaScript自定义数组排序方法
2015/02/12 Javascript
jQuery实现冻结表格行和列
2015/04/29 Javascript
js动态生成Html元素实现Post操作(createElement)
2015/09/14 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
jQuery图片拖动组件Dropzone用法示例
2017/01/17 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
解决vue2.x中数据渲染以及vuex缓存的问题
2017/07/13 Javascript
js实现带进度条提示的多视频上传功能
2020/12/13 Javascript
vue src动态加载请求获取图片的方法
2018/10/17 Javascript
9102年webpack4搭建vue项目的方法步骤
2019/02/20 Javascript
浅谈JavaScript中你可能不知道URL构造函数的属性
2020/07/13 Javascript
[02:04]2014DOTA2国际邀请赛 DK一个时代的落幕
2014/07/21 DOTA
[04:47]DOTA2-潍坊风行电子俱乐部探秘
2014/08/08 DOTA
python中退出多层循环的方法
2018/11/27 Python
树莓派+摄像头实现对移动物体的检测
2019/06/22 Python
Python Selenium安装及环境配置的实现
2020/03/17 Python
Python如何输出警告信息
2020/07/30 Python
澳大利亚拥有最佳跳伞降落点和最好服务的跳伞项目运营商:Skydive Australia
2018/03/05 全球购物
墨西哥网上超市:Superama
2018/07/10 全球购物
C,C++的几个面试题小集
2013/07/13 面试题
小学班长竞选演讲稿
2014/04/24 职场文书
环保倡议书500字
2014/05/15 职场文书
护士找工作求职信
2014/07/02 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
如何用 Python 子进程关闭 Excel 自动化中的弹窗
2021/05/07 Python
Python用any()函数检查字符串中的字母以及如何使用all()函数
2022/04/14 Python