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 正则式 概述及常用字符
May 07 Python
python实现基本进制转换的方法
Jul 11 Python
python下调用pytesseract识别某网站验证码的实现方法
Jun 06 Python
Python爬取个人微信朋友信息操作示例
Aug 03 Python
Python清空文件并替换内容的实例
Oct 22 Python
python根据list重命名文件夹里的所有文件实例
Oct 25 Python
Python的bit_length函数来二进制的位数方法
Aug 27 Python
Python树莓派学习笔记之UDP传输视频帧操作详解
Nov 15 Python
Python 函数绘图及函数图像微分与积分
Nov 20 Python
pandas to_excel 添加颜色操作
Jul 14 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
python Autopep8实现按PEP8风格自动排版Python代码
Mar 02 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服务器实现多session并发运行
2006/10/09 PHP
PHP 数组基础知识小结
2010/08/20 PHP
php目录操作函数之获取目录与文件的类型
2010/12/29 PHP
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
PHP手机号码及邮箱正则表达式实例解析
2020/07/11 PHP
js对文章内容进行分页示例代码
2014/03/05 Javascript
JavaScript常用脚本汇总(二)
2015/03/04 Javascript
jquery.mousewheel实现整屏翻屏效果
2015/08/30 Javascript
jQuery使用模式窗口实现在主页面和子页面中互相传值的方法
2016/03/01 Javascript
JS返回只包含数字类型的数组实例分析
2016/12/16 Javascript
JSON对象转化为字符串详解
2017/08/11 Javascript
vue Element-ui input 远程搜索与修改建议显示模版的示例代码
2017/10/19 Javascript
深入研究React中setState源码
2017/11/17 Javascript
jQuery实现新闻播报滚动及淡入淡出效果示例
2018/03/23 jQuery
vue-cli2.9.3 详细教程
2018/04/23 Javascript
详解微信小程序input标签正则初体验
2018/08/18 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
elementUI Tree 树形控件的官方使用文档
2019/04/25 Javascript
如何写好一个vue组件,老夫的一年经验全在这了(推荐)
2019/05/18 Javascript
jQuery表单校验插件validator使用方法详解
2020/02/18 jQuery
python threading模块操作多线程介绍
2015/04/08 Python
python抓取网页中链接的静态图片
2018/01/29 Python
tensorflow实现简单的卷积网络
2018/05/24 Python
Flask框架实现给视图函数增加装饰器操作示例
2018/07/16 Python
Python简单获取二维数组行列数的方法示例
2018/12/21 Python
python交易记录整合交易类详解
2019/07/03 Python
python使用requests.session模拟登录
2019/08/09 Python
python中seaborn包常用图形使用详解
2019/11/25 Python
tensorboard实现同时显示训练曲线和测试曲线
2020/01/21 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
HTML5中的新元素介绍
2008/10/17 HTML / CSS
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
Sneaker Studio捷克:购买运动鞋
2018/07/08 全球购物
C语言如何决定使用那种整数类型
2016/11/26 面试题
优秀本科毕业生自荐信
2014/07/04 职场文书