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分割和拼接字符串
Nov 01 Python
Django1.3添加app提示模块不存在的解决方法
Aug 26 Python
CentOS安装pillow报错的解决方法
Jan 27 Python
Python科学计算之Pandas详解
Jan 15 Python
python MysqlDb模块安装及其使用详解
Feb 23 Python
对python3中pathlib库的Path类的使用详解
Oct 14 Python
Python 3.x基于Xml数据的Http请求方法
Dec 28 Python
Python设计模式之工厂方法模式实例详解
Jan 18 Python
详解numpy的argmax的具体使用
May 27 Python
Python 堆叠柱状图绘制方法
Jul 29 Python
opencv 图像滤波(均值,方框,高斯,中值)
Jul 08 Python
Django中使用Celery的方法步骤
Dec 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设置允许大文件上传示例代码
2014/03/10 PHP
php生成二维码
2015/08/10 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
2016/05/06 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
js滚动条多种样式,推荐
2007/02/05 Javascript
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
原生js写的放大镜效果
2012/08/22 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
JS清除字符串中重复值的实现方法
2016/08/03 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
nodejs开发微信小程序实现密码加密
2017/07/11 NodeJs
vue+node+webpack环境搭建教程
2017/11/05 Javascript
D3.js实现简洁实用的动态仪表盘的示例
2018/04/04 Javascript
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
vue.js实现回到顶部动画效果
2019/07/31 Javascript
微信小程序前端promise封装代码实例
2019/08/24 Javascript
p5.js绘制旋转的正方形
2019/10/23 Javascript
JS精确判断数据类型代码实例
2019/12/18 Javascript
js表达式与运算符简单操作示例
2020/02/15 Javascript
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
phpsir 开发 一个检测百度关键字网站排名的python 程序
2009/09/17 Python
在Python中使用base64模块处理字符编码的教程
2015/04/28 Python
使用Python如何测试InnoDB与MyISAM的读写性能
2018/09/18 Python
详解python pandas 分组统计的方法
2019/07/30 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
SHEIN美国:购买时髦的女性服装
2020/12/02 全球购物
策划总监岗位职责
2014/02/16 职场文书
小小的船教学反思
2014/02/21 职场文书
大专毕业生自我鉴定范文(2篇)
2014/09/27 职场文书
2014年党建工作总结
2014/11/11 职场文书
学校元旦晚会开场白
2014/12/14 职场文书
小公司融资,商业计划书的8切记
2019/07/15 职场文书
HTML中table表格拆分合并(colspan、rowspan)
2021/04/07 HTML / CSS
vue+spring boot实现校验码功能
2021/05/27 Vue.js