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中使用next()方法操作文件的教程
May 24 Python
Python2.7 实现引入自己写的类方法
Apr 29 Python
基于python历史天气采集的分析
Feb 14 Python
如何使用Python标准库进行性能测试
Jun 25 Python
Python Pandas分组聚合的实现方法
Jul 02 Python
python Tcp协议发送和接收信息的例子
Jul 22 Python
python实现将json多行数据传入到mysql中使用
Dec 31 Python
python__new__内置静态方法使用解析
Jan 07 Python
python add_argument()用法解析
Jan 29 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
Jun 23 Python
python numpy中setdiff1d的用法说明
Apr 22 Python
教你怎么用python selenium实现自动化测试
May 27 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大批量插入数据库的3种方法和速度对比
2014/07/08 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
PHP在线打包下载功能示例
2016/10/15 PHP
使用PHP+MySql实现微信投票功能实例代码
2017/09/29 PHP
laravel邮件发送的实现代码示例
2020/01/31 PHP
js+css实现增加表单可用性之提示文字
2013/06/03 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
JSONObject使用方法详解
2015/12/17 Javascript
jQuery的框架介绍
2016/05/11 Javascript
Adapter适配器模式在JavaScript设计模式编程中的运用分析
2016/05/18 Javascript
JavaScript函数节流概念与用法实例详解
2016/06/20 Javascript
jQuery 循环遍历改变a标签的href(实例讲解)
2017/07/12 jQuery
js前端导出Excel的方法
2017/11/01 Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
2018/05/24 jQuery
Webpack devServer中的 proxy 实现跨域的解决
2018/06/15 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
2019/09/16 Javascript
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
原生js实现随机点餐效果
2019/12/10 Javascript
Jquery Datatables的使用详解
2020/01/30 jQuery
Python中的True,False条件判断实例分析
2015/01/12 Python
Python3多线程操作简单示例
2018/05/22 Python
详解Django解决ajax跨域访问问题
2018/08/24 Python
用Python实现读写锁的示例代码
2018/11/05 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
python实现五子棋游戏
2019/06/18 Python
Python通过字典映射函数实现switch
2020/11/06 Python
MySQL面试题目集锦
2016/04/14 面试题
护理专科毕业生自荐书范文
2014/02/19 职场文书
《植物妈妈有办法》教学反思
2014/02/25 职场文书
党的群众路线教育实践活动通讯稿
2014/09/10 职场文书
办公室年度工作总结2015
2015/05/21 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
如何写通讯稿
2015/07/22 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
Go Plugins插件的实现方式
2021/08/07 Golang
python如何读取和存储dict()与.json格式文件
2022/06/25 Python