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

作者:叶袖清风 时间:2023-08-04 01:06:58 

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

来源:https://juejin.im/post/5c6b64bde51d457fa31e6a30

标签:django,小程序,登录验证
0
投稿

猜你喜欢

  • Python必备技巧之函数的使用详解

    2021-03-02 11:19:59
  • Python Pyinstaller库安装步骤以及使用方法

    2021-05-12 07:07:26
  • Python实现的HMacMD5加密算法示例

    2022-01-15 06:05:31
  • python list.sort()根据多个关键字排序的方法实现

    2021-05-22 03:16:09
  • vue2.0项目集成Cesium的实现方法

    2024-06-07 15:22:22
  • YOLOv5改进之添加CBAM注意力机制的方法

    2023-07-22 20:48:52
  • Python高级特性之闭包与装饰器实例详解

    2021-09-19 03:17:25
  • OpenCV物体跟踪树莓派视觉小车实现过程学习

    2021-09-15 21:55:48
  • Jenkins配置maven项目之打包、部署、发布的全过程

    2023-08-07 19:14:29
  • SQL Server2005打开数据表中的XML内容时报错的解决办法

    2024-01-18 01:32:12
  • Python调用graphviz绘制结构化图形网络示例

    2021-09-15 19:06:49
  • python 两种方法修改文件的创建时间、修改时间、访问时间

    2023-08-10 03:06:52
  • 在SQL Server中使用CLR调用.NET方法

    2008-12-24 15:43:00
  • python实现21点小游戏

    2023-11-21 08:58:27
  • 如何通过shell脚本自动生成vue文件详解

    2024-05-22 10:28:35
  • 如何利用触发器实现两个数据库间的同步

    2009-01-06 11:26:00
  • 基于python实现查询ip地址来源

    2021-02-10 14:45:52
  • ASPImage组件的实现过程[图]

    2008-02-03 15:37:00
  • OpenCV全景图像拼接的实现示例

    2021-12-04 00:36:09
  • MySQL配置文件my.cnf中文版

    2011-09-30 11:06:15
  • asp之家 网络编程 m.aspxhome.com