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 相关文章推荐
数据挖掘之Apriori算法详解和Python实现代码分享
Nov 07 Python
教你用Python脚本快速为iOS10生成图标和截屏
Sep 22 Python
Python判断某个用户对某个文件的权限
Oct 13 Python
python搭建服务器实现两个Android客户端间收发消息
Apr 12 Python
Python django使用多进程连接mysql错误的解决方法
Oct 08 Python
Python第三方库h5py_读取mat文件并显示值的方法
Feb 08 Python
python实现定时压缩指定文件夹发送邮件
Dec 22 Python
Python流程控制 if else实现解析
Sep 02 Python
基于Python实现人脸自动戴口罩系统
Feb 06 Python
.img/.hdr格式转.nii格式的操作
Jul 01 Python
基于Python组装jmx并调用JMeter实现压力测试
Nov 03 Python
Python各协议下socket黏包问题原理
Apr 12 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
IP138 IP地址查询小偷实现代码
2010/02/15 PHP
小文件php+SQLite存储方案
2010/09/04 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
PHP如何获取当前主机、域名、网址、路径、端口等参数
2017/06/09 PHP
PHP+MySQL实现输入页码跳转到指定页面功能示例
2018/06/01 PHP
游戏人文件夹程序 ver 3.0
2006/07/14 Javascript
客户端脚本中常常出现的一些问题和调试技巧
2007/01/09 Javascript
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
JQuery.ajax传递中文参数的解决方法 推荐
2011/03/28 Javascript
js判读浏览器是否支持html5的canvas的代码
2013/11/18 Javascript
禁用JavaScript控制台调试的方法
2014/03/07 Javascript
加随机数引入脚本不让浏览器读取缓存
2014/09/04 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
微信小程序与php 实现微信支付的简单实例
2017/06/23 Javascript
jQuery EasyUI的TreeGrid查询功能实现方法
2017/08/08 jQuery
js实现一个页面多个倒计时的3种方法
2019/02/25 Javascript
vue 项目中当访问路由不存在的时候默认访问404页面操作
2020/08/31 Javascript
python实现搜索本地文件信息写入文件的方法
2016/02/22 Python
Python常用知识点汇总
2016/05/08 Python
python实现支付宝当面付(扫码支付)功能
2018/05/30 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
tensorflow 获取checkpoint中的变量列表实例
2020/02/11 Python
健康教育评估方案
2014/05/25 职场文书
聘用意向书
2014/07/29 职场文书
学校交通安全责任书
2014/08/25 职场文书
团委工作总结2015
2015/04/02 职场文书
信息技术课教学反思
2016/02/23 职场文书
python3.9之你应该知道的新特性详解
2021/04/29 Python
MySQL千万级数据表的优化实战记录
2021/08/04 MySQL