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 相关文章推荐
关于pip的安装,更新,卸载模块以及使用方法(详解)
May 19 Python
python编写Logistic逻辑回归
Dec 30 Python
python创建文件时去掉非法字符的方法
Oct 31 Python
对Python w和w+权限的区别详解
Jan 23 Python
python实现贪吃蛇小游戏
Mar 21 Python
我用Python抓取了7000 多本电子书案例详解
Mar 25 Python
python assert的用处示例详解
Apr 01 Python
django项目简单调取百度翻译接口的方法
Aug 06 Python
在Pycharm中安装Pandas库方法(简单易懂)
Feb 20 Python
如何用python爬取微博热搜数据并保存
Feb 20 Python
python中if和elif的区别介绍
Nov 07 Python
Python如何利用pandas读取csv数据并绘图
Jul 07 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学习之输出字符串(echo,print,printf,print_r和var_dump)
2011/04/17 PHP
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
php ckeditor上传图片文件名乱码解决方法
2013/11/15 PHP
php静态文件返回304技巧分享
2015/01/06 PHP
PHP输出一个等腰三角形的方法
2015/05/12 PHP
Laravel 数据库加密及数据库表前缀配置方法
2019/10/10 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
javascript开发随笔二 动态加载js和文件
2011/11/25 Javascript
拥抱模块化的JavaScript
2012/03/07 Javascript
js获得地址栏?问号后参数的方法
2013/08/08 Javascript
JavaScript基础进阶之数组方法总结(推荐)
2017/09/04 Javascript
Vue中组件之间数据的传递的示例代码
2017/09/08 Javascript
vue和webpack项目构建过程常用的npm命令详解
2018/06/15 Javascript
vue实现信息管理系统
2020/05/30 Javascript
[01:05:30]VP vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python批量同步web服务器代码核心程序
2014/09/01 Python
基于Python闭包及其作用域详解
2017/08/28 Python
python3.5+tesseract+adb实现西瓜视频或头脑王者辅助答题
2018/01/17 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
2018/10/22 Python
python批量赋值操作实例
2018/10/22 Python
python执行CMD指令,并获取返回的方法
2018/12/19 Python
Python语言进阶知识点总结
2019/05/28 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
Python 统计位数为偶数的数字代码详解
2020/03/15 Python
用python发送微信消息
2020/12/21 Python
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
简历自荐信
2013/12/02 职场文书
会计专业毕业自荐书范文
2014/02/08 职场文书
股指期货心得体会
2014/09/13 职场文书
批评与自我批评发言稿
2014/10/15 职场文书
新员工实习期个人工作总结
2015/10/15 职场文书
银行柜员优质服务心得体会
2016/01/22 职场文书
HTML基本元素标签介绍
2022/02/28 HTML / CSS
Python自动化工具之实现Excel转Markdown表格
2022/04/08 Python
使用python绘制分组对比柱状图
2022/04/21 Python