微信小程序登录对接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 相关文章推荐
jquery 屏蔽一个区域内的所有元素,禁止输入
Oct 22 Javascript
限制文本框输入N个字符的js代码
May 13 Javascript
JavaScript 语言基础知识点总结(思维导图)
Nov 10 Javascript
Jquery解析json数据详解
Dec 26 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
Mar 23 Javascript
在JavaScript的jQuery库中操作AJAX的方法讲解
Aug 15 Javascript
基于jQuery实现选取月份插件附源码下载
Dec 28 Javascript
详解微信小程序开发之下拉刷新 上拉加载
Nov 24 Javascript
jQuery实现拖动效果的实例代码
Jun 25 jQuery
jQuery事件_动力节点Java学院整理
Jul 05 jQuery
JS eval代码快速解密实例解析
Apr 23 Javascript
仿照Element-ui实现一个简易的$message方法
Sep 14 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循环输出数据库内容的代码
2008/05/24 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
Laravel框架实现的批量删除功能示例
2019/01/16 PHP
Alliance vs AM BO3 第一场2.13
2021/03/10 DOTA
Jquery 数组操作大全个人总结
2013/11/13 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
2014/05/08 Javascript
13 款最热门的 jQuery 图像 360 度旋转插件推荐
2014/12/09 Javascript
jQuery中$.click()无效问题分析
2015/01/29 Javascript
JavaScript获取当前运行脚本文件所在目录的方法
2016/02/03 Javascript
JavaScript数据存储 Cookie篇
2016/07/02 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
mui上拉加载功能实例详解
2017/04/13 Javascript
Vue导出json数据到Excel电子表格的示例
2017/12/04 Javascript
Vue 项目部署到服务器的问题解决方法
2017/12/05 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
详解vscode中vue代码颜色插件
2018/10/11 Javascript
layui点击弹框页面 表单请求的方法
2019/09/21 Javascript
Python实现统计代码行的方法分析
2017/07/12 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
python时间time模块处理大全
2020/10/25 Python
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
canvas因为图片资源不在同一域名下而导致的跨域污染画布的解决办法
2019/01/18 HTML / CSS
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
Gap英国官网:Gap UK
2018/07/18 全球购物
Redbubble法国:由独立艺术家设计的独特产品
2019/01/08 全球购物
澳大利亚最受欢迎的美发用品目的地:AMR
2019/08/28 全球购物
八一建军节活动方案
2014/02/10 职场文书
迎元旦广播稿
2014/02/22 职场文书
抽样调查项目计划书
2014/04/24 职场文书
读书之星事迹材料
2014/05/12 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
护士求职自荐信
2015/03/25 职场文书
2015年幼儿园班务工作总结
2015/05/12 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
Android Flutter实现图片滑动切换效果
2022/04/07 Java/Android