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中__slots__用法实例
Jun 04 Python
python处理html转义字符的方法详解
Jul 01 Python
python 将字符串转换成字典dict的各种方式总结
Mar 23 Python
TensorFlow数据输入的方法示例
Jun 19 Python
Django进阶之CSRF的解决
Aug 01 Python
python将.ppm格式图片转换成.jpg格式文件的方法
Oct 27 Python
django中使用Celery 布式任务队列过程详解
Jul 29 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
Mar 06 Python
python如何利用paramiko执行服务器命令
Nov 07 Python
python不同版本的_new_不同点总结
Dec 09 Python
利用For循环遍历Python字典的三种方法实例
Mar 25 Python
Python使用mitmproxy工具监控手机 下载手机小视频
Apr 18 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源代码
2006/10/09 PHP
PHP JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
2017/05/05 PHP
基于jquery用于查询操作的实现代码
2010/05/10 Javascript
jquery 多行滚动代码(附详细解释)
2010/06/17 Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
2013/05/19 Javascript
JavaScript实现的日期控件具体代码
2013/11/18 Javascript
jquery Validation表单验证使用详解
2020/09/12 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
简单实现JS对dom操作封装
2015/12/02 Javascript
EasyUI创建对话框的两种方式
2016/08/23 Javascript
利用jquery实现瀑布流3种案例
2016/09/18 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
js实现百度地图定位于地址逆解析,显示自己当前的地理位置
2016/12/08 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
webpack-mvc 传统多页面组件化开发详解
2019/05/07 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
2019/05/27 Javascript
微信小程序点击滚动到指定位置的实现
2020/05/22 Javascript
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
Python 调用DLL操作抄表机
2009/01/12 Python
python打开文件并获取文件相关属性的方法
2015/04/23 Python
Python 实现12306登录功能实例代码
2018/02/09 Python
python之DataFrame实现excel合并单元格
2021/02/22 Python
Python pygame绘制文字制作滚动文字过程解析
2019/12/12 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
Python通过Tesseract库实现文字识别
2020/03/05 Python
python实现人机五子棋
2020/03/25 Python
Python 实现PS滤镜的旋涡特效
2020/12/03 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
Maisons du Monde德国:法国家具和装饰的市场领导者
2019/07/26 全球购物
中专毕业生自荐信
2013/11/16 职场文书
优秀毕业生求职信范文
2014/01/02 职场文书
给老师的感谢信
2015/01/20 职场文书
国庆放假通知怎么写
2015/07/30 职场文书
Python3 如何开启自带http服务
2021/05/18 Python