微信小程序登录对接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的$.ajax async使用
Oct 19 Javascript
js实现div闪烁原理及实现代码
Jun 24 Javascript
javascript排序函数实现数字排序
Jun 26 Javascript
Javascript计算二维数组重复值示例代码
Dec 18 Javascript
jQuery实现Table表格隔行变色及高亮显示当前选择行效果示例
Feb 14 Javascript
VUE多层路由嵌套实现代码
May 15 Javascript
cocos creator Touch事件应用(触控选择多个子节点的实例)
Sep 10 Javascript
vue组件watch属性实例讲解
Nov 07 Javascript
laydate日历控件使用方法详解
Nov 20 Javascript
vue 实现全选全不选的示例代码
Mar 29 Javascript
webpack中的模式(mode)使用详解
Feb 20 Javascript
手写Vue源码之数据劫持示例详解
Jan 04 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
一些被忽视的PHP函数(简单整理)
2010/04/30 PHP
php生成缩略图填充白边(等比缩略图方案)
2013/12/25 PHP
PHP小教程之实现链表
2014/06/09 PHP
php字符比较函数similar_text、strnatcmp与strcasecmp用法分析
2014/11/18 PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
2016/04/02 PHP
php桥接模式应用案例分析
2019/10/23 PHP
简明json介绍
2008/09/28 Javascript
jquery自定义下拉列表示例
2014/04/25 Javascript
用js模拟struts2的多action调用示例
2014/05/19 Javascript
js封装可使用的构造函数继承用法分析
2015/01/28 Javascript
vue实现element-ui对话框可拖拽功能
2018/08/17 Javascript
微信小程序canvas实现签名功能
2021/01/19 Javascript
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
[01:03:33]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
Python中unittest模块做UT(单元测试)使用实例
2015/06/12 Python
python实现线程池的方法
2015/06/30 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
CentOS7下python3.7.0安装教程
2018/07/30 Python
python  创建一个保留重复值的列表的补码
2018/10/15 Python
wxPython实现整点报时
2019/11/18 Python
Python PyPDF2模块安装使用解析
2020/01/19 Python
win10安装python3.6的常见问题
2020/07/01 Python
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
印尼披萨外送专家:Domino’s Pizza印尼
2017/12/28 全球购物
泰国第一的化妆品网站:Konvy
2018/02/25 全球购物
新闻专业个人自我评价
2013/09/21 职场文书
会计岗位描述
2014/02/22 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
2014年学校办公室工作总结
2014/12/19 职场文书
2015年房地产销售工作总结
2015/04/20 职场文书
2015年学校减负工作总结
2015/05/19 职场文书
新郎父母婚礼致辞
2015/07/27 职场文书
创业计划书之甜品店
2019/09/18 职场文书
我的收音机情缘
2022/04/05 无线电
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android