django与小程序实现登录验证功能的示例代码


Posted in Python onFebruary 19, 2019

之前用小程序做项目,因为后台使用的java开发,一切顺利,但切换成django做RESTful API接口时,在登陆注册时一直出现问题,网上搜索,借助一个网友的回答,找到了一种可行的解决方案,现记录如下。

具体流程

  • 用户点击小程序页面上的登录授权认证
  • 通过微信自带的认证获取code
  • 调取登录接口,将code传入后台
  • 后台拿到code调用微信接口获取openid等用户信息
  • 后台将openid作为用户名,若存在则去校验用户信息,否则以此用户名创建新用户,密码随机生成
  • 将校验结果或者创建信息返回给微信小程序端
  • 根据返回的信息完成用户登录校验

django的用户权限认证

django有一套自己的完善用户模型,由于Django Auth自带的User模型字段有限,我们需要对其进行拓展(直接使用也可以)

nickname = models.CharField(verbose_name=u'昵称',max_length=50, blank=True)
user_avatar = models.ImageField(verbose_name=u'用户头像', upload_to='image/%Y/%m/%d', default=u'image/default.png', max_length=500)
user_email = models.EmailField(verbose_name=u'用户邮箱',max_length=254)
user_phone = models.BigIntegerField(verbose_name=u'手机号', null=True,blank=True)
user_birthday = models.DateField(verbose_name=u'出生日期', default = timezone.now)
user_sex = models.CharField(verbose_name=u'性别',max_length=6,choices=(('male','男'),('female','女')),default='male')
user_address = models.CharField(verbose_name=u'地址',max_length=550, blank=True,null=True)
signature = models.CharField(verbose_name=u'个性签名',max_length=550, blank=True,null=True)

用户接口序列化

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
class Meta:
  model = User
  fields = "__all__"

登陆接口设计

class UserLogin(APIView):
  def post(self,request):
    params = request.data
    userName = get_openid(params.get('code'))
    userInfo = params.get('userinfo')
    try:
      user = User.objects.get(username = userName)
    except Exception as e:
      user = None
    if user:
      # 更新用户信息
      user = User.objects.get(username = userName)
    else:
      #注册新用户
      user = User.objects.create_user(username=userName,password=random_str(10))  
    #手动生成JWT
    # 手动生成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)

    ret = {'code': '00000', 'msg': None,'data':{}}
    
    ret['msg'] = '授权成功'
    ret['data'] = {
      'token': token,
      'user_id': user.id,
      'nickname': user.nickname
    }
    return JsonResponse(ret)

解析code获取openid

class OpenidUtils(object):
  def __init__(self, jscode):
    self.url = "https://api.weixin.qq.com/sns/jscode2session"
    self.appid = APPID
    self.secret = SECRET
    self.jscode = jscode  # 前端传回的动态jscode

  def get_openid(self):
    url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"
    r = requests.get(url)
    openid = r.json()['openid']
    return openid

小程序的登陆验证

具体登录流程可以查阅官方文档。

function getWXUserInfo() {
  const login = promisify(wx.login);
  const getUserInfo = promisify(wx.getUserInfo);

  return new Promise(function (resolve, reject) {
    _wxLogin();
    function _wxLogin() {
      login().then(function (res) {
        getUserInfo().then(function (r) {
          let userInfo = r;
          userInfo.code = res.code;
          try {
            wx.setStorageSync('userInfo', userInfo);
          } catch (e) {
            console.log(e)
          }
          if (userInfo && userInfo.code && userInfo.iv) {
            resolve(userInfo);
          }
          else {
            reject('wx login fail');
          }
        }).catch(function (error) {
          reject(error);
        });
      }).catch(function (error) {
        reject(error);
      });
    }
  });
}

//登录接口验证
getWXUserInfo().then(function (data) {
  var result = {
    code: 0,
    data: {}
  };
  var params = {
    'code':data.code,
    'userinfo':data.userInfo
  }
  wx.request({
    url: '/api/login',
    data: params,
    dataType: 'json',
    method: 'POST',
    success: function (response) {
      // 返回成功
      if (response.data && response.data.code == '00000') {
        try {
          var resData = {
            custNo: data.user_id,
            nickname: data.nickname
          };
          result.code = 0;
          result.data = resData;
          resolve(result);
        }
        catch (e) {
          console.warn(result)
          // 登录失败
          result.code = 2;
          resolve(result);
        }
      }
      else {
        // 获取 customNum 失败
        console.warn(result)
        result.code = 1;
        result.data = 'get customNum fail';
        resolve(result);
      }
    }
  })
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python读取csv文件示例(python操作csv)
Mar 11 Python
Python函数可变参数定义及其参数传递方式实例详解
May 25 Python
KMP算法精解及其Python版的代码示例
Jun 01 Python
Java多线程编程中ThreadLocal类的用法及深入
Jun 21 Python
使用django-crontab实现定时任务的示例
Feb 26 Python
python实现猜单词小游戏
May 22 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
Mar 30 Python
OpenCV图像颜色反转算法详解
May 13 Python
Python线程协作threading.Condition实现过程解析
Mar 12 Python
Opencv 图片的OCR识别的实战示例
Mar 02 Python
Python 实现绘制子图及子图刻度的变换等问题
May 31 Python
Python并发编程实例教程之线程的玩法
Jun 20 Python
实例讲解Python3中abs()函数
Feb 19 #Python
python协程之动态添加任务的方法
Feb 19 #Python
Python同步遍历多个列表的示例
Feb 19 #Python
python读取txt文件并取其某一列数据的示例
Feb 19 #Python
详解Python3注释知识点
Feb 19 #Python
Python3解释器知识点总结
Feb 19 #Python
python 利用文件锁单例执行脚本的方法
Feb 19 #Python
You might like
PHP读取、解析eml文件及生成网页的方法示例
2017/09/04 PHP
php7 错误处理机制修改实例分析
2020/05/25 PHP
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
2011/01/08 Javascript
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
简单实用的反馈表单无刷新提交带验证
2013/11/15 Javascript
document.write的几点使用心得
2014/05/14 Javascript
原生js制作简单的数字键盘
2015/04/24 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
2015/05/13 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
实例详解jQuery结合GridView控件的使用方法
2016/01/04 Javascript
基于javascript实现表格的简单操作
2016/05/21 Javascript
d3.js中冷门却实用的内置函数总结
2017/02/04 Javascript
js图片放大镜效果实现方法详解
2020/10/28 Javascript
Angular中ng-bind和ng-model的区别实例详解
2017/04/10 Javascript
vue基于mint-ui的城市选择3级联动的示例
2017/10/25 Javascript
利用SpringMVC过滤器解决vue跨域请求的问题
2018/02/10 Javascript
解决vue+webpack打包路径的问题
2018/03/06 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
使用 vue 实现灭霸打响指英雄消失的效果附demo
2019/05/06 Javascript
vue+高德地图写地图选址组件的方法
2019/05/18 Javascript
Python中字符串的修改及传参详解
2016/11/30 Python
Python并发之多进程的方法实例代码
2018/08/15 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
python logging日志模块原理及操作解析
2019/10/12 Python
解决django无法访问本地static文件(js,css,img)网页里js,cs都加载不了
2020/04/07 Python
彻底搞懂python 迭代器和生成器
2020/09/07 Python
python 5个实用的技巧
2020/09/27 Python
用python写PDF转换器的实现
2020/10/29 Python
同步和异步有何异同,在什么情况下分别使用他们?举例说明
2014/02/27 面试题
介绍下WebSphere的安全性
2013/01/31 面试题
薪酬专员岗位职责
2014/02/18 职场文书
2014年机关植树节活动方案
2014/02/27 职场文书
《哪吒闹海》教学反思
2014/02/28 职场文书
知识竞赛主持词
2014/03/26 职场文书
2015年加油站工作总结
2015/05/13 职场文书