微信小程序登录对接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实例教程(19) 使用HoTMetal(1)
Dec 23 Javascript
javascript 遍历验证所有文本框的值
Aug 27 Javascript
extjs 为某个事件设置拦截器
Jan 15 Javascript
js 表单提交后按钮变灰的实例代码
Aug 16 Javascript
获取select元素被选中的文本内容的js代码
Jan 29 Javascript
详解JavaScript编程中正则表达式的使用
Oct 25 Javascript
百度搜索框智能提示案例jsonp
Nov 28 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
Jan 19 Javascript
防止页面url缓存中ajax中post请求的处理方法
Oct 10 Javascript
jQuery实现监听下拉框选中内容发生改变操作示例
Jul 13 jQuery
基于vue写一个全局Message组件的实现
Aug 15 Javascript
vue实现节点增删改功能
Sep 26 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&mysql(三)
2006/10/09 PHP
用PHP来写记数器(详细介绍)
2006/10/09 PHP
第一节--面向对象编程
2006/11/16 PHP
简单的PHP留言本实例代码
2010/05/09 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
解析csv数据导入mysql的方法
2013/07/01 PHP
PDO的安全处理与事物处理方法
2016/10/31 PHP
PHPExcel 修改已存在Excel的方法
2018/05/03 PHP
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
JavaScript将数据转换成整数的方法
2014/01/04 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
jQuery电话号码验证实例
2017/01/05 Javascript
jQuery获取table下某一行某一列的值实现代码
2017/04/07 jQuery
node.js express中app.param的用法详解
2017/07/16 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
详解javascript replace高级用法
2019/02/17 Javascript
ES6小技巧之代替lodash
2019/06/07 Javascript
详解基于Vue的支持数据双向绑定的select组件
2019/09/02 Javascript
vue 实现cli3.0中使用proxy进行代理转发
2019/10/30 Javascript
[36:41]完美世界DOTA2联赛循环赛FTD vs Magma第一场 10月30日
2020/10/31 DOTA
pyv8学习python和javascript变量进行交互
2013/12/04 Python
粗略分析Python中的内存泄漏
2015/04/23 Python
python中的错误处理
2016/04/10 Python
python 实现登录网页的操作方法
2018/05/11 Python
python 基本数据类型占用内存空间大小的实例
2018/06/12 Python
在Pycharm中使用GitHub的方法步骤
2019/06/13 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
2020/03/26 Python
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
NBA欧洲商店(西班牙):NBA Europe Store ES
2019/04/16 全球购物
荷兰在线钓鱼商店:Raven
2019/06/26 全球购物
少先队学雷锋活动月总结
2014/03/09 职场文书
新教师培训心得体会
2014/09/02 职场文书
2019年朋友圈经典励志语录50条
2019/07/05 职场文书
2019年特色火锅店的创业计划书模板
2019/08/28 职场文书
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL