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通过scapy获取局域网所有主机mac地址示例
May 04 Python
Python 3.6 性能测试框架Locust安装及使用方法(详解)
Oct 11 Python
Java及python正则表达式详解
Dec 27 Python
django模板结构优化的方法
Feb 28 Python
Numpy数组array和矩阵matrix转换方法
Aug 05 Python
基于numpy中的expand_dims函数用法
Dec 18 Python
python实现局域网内实时通信代码
Dec 22 Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 Python
python处理写入数据代码讲解
Oct 22 Python
python读取pdf格式文档的实现代码
Apr 01 Python
Python 快速验证代理IP是否有效的方法实现
Jul 15 Python
在Python 中将类对象序列化为JSON
Apr 06 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函数
2010/01/11 PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
php截取中文字符串函数实例
2015/02/23 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
2018/03/31 PHP
学习js在线html(富文本,所见即所得)编辑器
2012/12/18 Javascript
js获取或设置当前窗口url参数的小例子
2013/10/14 Javascript
JQuery文本改变触发事件如聚焦事件、失焦事件
2014/01/15 Javascript
现如今最流行的JavaScript代码规范
2014/03/08 Javascript
7个让JavaScript变得更好的注意事项
2015/01/28 Javascript
javascript笛卡尔积算法实现方法
2015/04/08 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
JS验证 只能输入小数点,数字,负数的实现方法
2016/10/07 Javascript
javascript显示系统当前时间代码
2016/12/29 Javascript
ES6正则表达式的一些新功能总结
2017/05/09 Javascript
vue子组件使用自定义事件向父组件传递数据
2017/05/27 Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
2017/09/11 Javascript
jquery ztree实现右键收藏功能
2017/11/20 jQuery
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
2019/05/26 Javascript
vue子路由跳转实现tab选项卡
2019/07/24 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
2019/09/03 Javascript
在ironpython中利用装饰器执行SQL操作的例子
2015/05/02 Python
python连接mongodb密码认证实例
2018/10/16 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
2019/04/29 Python
Pytorch 实现计算分类器准确率(总分类及子分类)
2020/01/18 Python
python+selenium+PhantomJS抓取网页动态加载内容
2020/02/25 Python
python能开发游戏吗
2020/06/11 Python
18-35岁旅游团的全球领导者:Contiki
2017/02/08 全球购物
亚历山大·王官网:Alexander Wang
2017/06/23 全球购物
加拿大床上用品、家居装饰、厨房和浴室产品购物网站:Linen Chest
2018/06/05 全球购物
绘儿乐产品官方在线商店:Crayola.com
2019/09/07 全球购物
2019年Java 最常见的 面试题
2016/10/19 面试题
商场经理竞聘演讲稿
2014/01/01 职场文书
《诺贝尔》教学反思
2014/02/17 职场文书
个人培训总结
2015/03/05 职场文书
CSS+HTML 实现顶部导航栏功能
2021/08/30 HTML / CSS