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中logging模块的用法实例
Sep 29 Python
python调用百度REST API实现语音识别
Aug 30 Python
Python 利用pydub库操作音频文件的方法
Jan 09 Python
python操作小程序云数据库实现简单的增删改查功能
Jun 06 Python
使用Python实现 学生学籍管理系统
Nov 26 Python
TensorFlow获取加载模型中的全部张量名称代码
Feb 11 Python
python数据预处理 :数据共线性处理详解
Feb 24 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
Apr 10 Python
Python获取浏览器窗口句柄过程解析
Jul 25 Python
如何把python项目部署到linux服务器
Aug 26 Python
通过代码实例了解Python sys模块
Sep 14 Python
python空元组在all中返回结果详解
Dec 15 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中的常用函数回顾
2013/07/11 PHP
PHP二维关联数组的遍历方式(实例讲解)
2017/10/18 PHP
laravel开发环境homestead搭建过程详解
2020/07/03 PHP
兼容多浏览器的字幕特效Marquee的通用js类
2008/07/20 Javascript
关于Jqzoom的使用心得 jquery放大镜效果插件
2010/04/12 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
jQuery中fadein与fadeout方法用法示例
2016/09/16 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
Javascript使用SWFUpload进行多文件上传
2016/11/16 Javascript
原生js封装自定义滚动条
2017/03/24 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
jQuery判断网页是否已经滚动到浏览器底部的实现方法
2017/10/27 jQuery
使用JS代码实现俄罗斯方块游戏
2018/08/03 Javascript
利用Promise自定义一个GET请求的函数示例代码
2019/03/20 Javascript
javascript操作元素的常见方法小结
2019/11/13 Javascript
javascript实现点击星星小游戏
2019/12/24 Javascript
JavaScript对象属性操作实例解析
2020/02/04 Javascript
Python中__init__和__new__的区别详解
2014/07/09 Python
详细介绍Python中的偏函数
2015/04/27 Python
解析Python中的异常处理
2015/04/28 Python
一个基于flask的web应用诞生 使用模板引擎和表单插件(2)
2017/04/11 Python
python3写爬取B站视频弹幕功能
2017/12/22 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
css3 实现圆形旋转倒计时
2018/02/24 HTML / CSS
html2 canvas生成清晰的图片实现打印功能
2019/09/23 HTML / CSS
澳大利亚顶级美发和美容贸易超市:glamaCo
2020/01/19 全球购物
世界上最大的艺术社区:SAA
2020/12/30 全球购物
幼儿如何来做好自我评价
2013/11/05 职场文书
委托书的格式
2014/08/01 职场文书
自我检讨书范文
2015/01/28 职场文书
欠条范文
2015/07/03 职场文书
教师病假条范文
2015/08/17 职场文书
高三数学教学反思
2016/02/18 职场文书
2016年最美孝心少年事迹材料
2016/02/26 职场文书
新手开公司创业注意事项有哪些?
2019/07/29 职场文书