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批量下载图片的三种方法
Apr 22 Python
python实现socket端口重定向示例
Feb 10 Python
python实现猜数字游戏(无重复数字)示例分享
Mar 29 Python
利用Python如何生成随机密码
Apr 20 Python
Python使用正则表达式实现文本替换的方法
Apr 18 Python
对django2.0 关联表的必填on_delete参数的含义解析
Aug 09 Python
Python Pandas对缺失值的处理方法
Sep 27 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 Python
python 在threading中如何处理主进程和子线程的关系
Apr 25 Python
python requests.get带header
May 05 Python
Python如何使用vars返回对象的属性列表
Oct 17 Python
python中判断数字是否为质数的实例讲解
Dec 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 数据库字段复用的基本原理与示例
2011/07/22 PHP
openflashchart 2.0 简单案例php版
2012/05/21 PHP
php函数array_merge用法一例(合并同类数组)
2013/02/03 PHP
php实现遍历目录并删除指定文件中指定内容
2015/01/21 PHP
PHP-X系列教程之内置函数的使用示例
2017/10/16 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
jquery创建表格(自动增加表格)代码分享
2013/12/25 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
JS实现alert中显示换行的方法
2015/12/17 Javascript
angularjs点击图片放大实现上传图片预览
2017/02/24 Javascript
js a标签点击事件
2017/03/30 Javascript
Angular弹出模态框的两种方式
2017/10/19 Javascript
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
Node.js创建Web、TCP服务器
2017/12/05 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
vue+webpack 更换主题N种方案优劣分析
2019/10/28 Javascript
vant picker+popup 自定义三级联动案例
2020/11/04 Javascript
原生JS实现音乐播放器的示例代码
2021/02/25 Javascript
在Django框架中伪造捕捉到的URLconf值的方法
2015/07/18 Python
Python编程之微信推送模板消息功能示例
2017/08/21 Python
Pycharm无法显示动态图片的解决方法
2018/10/28 Python
解决Python 使用h5py加载文件,看不到keys()的问题
2019/02/08 Python
ERLANG和PYTHON互通实现过程详解
2019/07/05 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
Python txt文件如何转换成字典
2020/11/03 Python
乐高积木玩具美国官网:LEGO Shop US
2016/09/16 全球购物
德国传统玻璃制造商:Cristalica
2018/04/23 全球购物
SIXPAD智能健身仪英国官网:革命性的训练装备品牌
2018/09/27 全球购物
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
生物学学生自我评价
2014/01/17 职场文书
生产部岗位职责范文
2014/02/07 职场文书
计算机系本科生求职信
2014/05/31 职场文书
2019年鼓励无偿献血倡议书
2019/09/17 职场文书
Navicat连接MySQL错误描述分析
2021/06/02 MySQL
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技