欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

django与小程序实现登录验证功能的示例代码

程序员文章站 2022-10-06 14:51:33
之前用小程序做项目,因为后台使用的java开发,一切顺利,但切换成django做restful api接口时,在登陆注册时一直出现问题,网上搜索,借助一个网友的回答,找到了...

之前用小程序做项目,因为后台使用的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);
      }
    }
  })
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。