• Django rest-framework框架-认证组件的简单实例


    第一版 :

    自己写函数实现用户认证

    #models
    from django.db import models
    #用户表
    class UserInfo(models.Model):
          user_type_choices=((1,'普通用户'),(2,'VIP'),(3,'SVIP'))
          user_type = models.IntegerField(choices=user_type_choices)
          username = models.CharFiled(max_length=32,uniquw=True)
          password = models.CharFiled(max_length=64)
    # 用登录成功的token
    class UserToken(models.Model):
          user = models.OneToOneFiled(to='UserInfo')
          token = models.CharFiled(max_length=64)
    # urls
    uplpatters= [
        url(r'^api/v1/auth/$', views.AuthView.as_view()),
    ]
    
    #views
    from  rest_framework.views import APIView
    from api import models
    
    # 生成随机字符串
    def Md5(user):
        import hashlib
        import time
        ctime = str(time.time())
        m = hashlib,md5(bytes(user,encodeing='utf-8'))
        m.update(bytes(ctime,encodeing='utf-8'))
        return m.hexdigest()
    
    class AuthView(APIView):
          """
          用户登录认证
          """
          def post(self,request,*args,**kwargs):
              try:
                user = request._reqeust.POST.get('username')
                pwd = request._reqeust.POST.get('password')
                obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
                if not obj:
                   ret['code'] = 1001
                   ret['msg'] = '用户名密码错误'
                # 为用户创建token
                token = Md5(user)
                # 如果存在token就更新 不存在就创建
                models.UserToken.objects.update_or_create(user=obj,defualts={'token':token})
                ret['token'] = token
              except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
              return JsonResponse()
    
    ORDER_DICT = {
        1:{
            'name': 'x',
            'age': 18,
            'gender':'y',
            'content': '...'
        },
        2:{
            'name': 'z',
            'age': 18,
            'gender': 'h',
            'content': '...'
        }
    }
     class OrderView(APIView):
           """
           订单业务
           """
           def get(self, request, *args,**kwargs):
               # token验证
               token = request._reqeust.GET.get('token')
               if not token:
                   return HttpResponse('用户未登录')
               
               ret={'code':1000,'msg':None,'data':None}
               try:
                   ret['data'] = ORDER_DICT
               except Exception as e:
                   pass
               return JsonResponse(ret)
    

    第二版: 改进版 

    使用restramework的authentication功能实现用户认证
    #models
    from django.db import models
    #用户表
    class UserInfo(models.Model):
          user_type_choices=((1,'普通用户'),(2,'VIP'),(3,'SVIP'))
          user_type = models.IntegerField(choices=user_type_choices)
          username = models.CharFiled(max_length=32,uniquw=True)
          password = models.CharFiled(max_length=64)
    # 用登录成功的token
    class UserToken(models.Model):
          user = models.OneToOneFiled(to='UserInfo')
          token = models.CharFiled(max_length=64)
    # urls
    uplpatters= [
        url(r'^api/v1/auth/$', views.AuthView.as_view()),
    ]
    
    #views
    from  rest_framework.views import APIView
    from api import models
    
    # 生成随机字符串
    def Md5(user):
        import hashlib
        import time
        ctime = str(time.time())
        m = hashlib,md5(bytes(user,encodeing='utf-8'))
        m.update(bytes(ctime,encodeing='utf-8'))
        return m.hexdigest()
    
    class AuthView(APIView):
          """
          用户登录认证
          """
          def post(self,request,*args,**kwargs):
              try:
                user = request._reqeust.POST.get('username')
                pwd = request._reqeust.POST.get('password')
                obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
                if not obj:
                   ret['code'] = 1001
                   ret['msg'] = '用户名密码错误'
                # 为用户创建token
                token = Md5(user)
                # 如果存在token就更新 不存在就创建
                models.UserToken.objects.update_or_create(user=obj,defualts={'token':token})
                ret['token'] = token
              except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
              return JsonResponse()
    
    
    
    ORDER_DICT = {
        1:{
            'name': 'x',
            'age': 18,
            'gender':'y',
            'content': '...'
        },
        2:{
            'name': 'z',
            'age': 18,
            'gender': 'h',
            'content': '...'
        }
    }
    
    from  rest_framework.request import Request
    from  rest_framework import exceptions
    class Authtication(object):
          """
          用户登录认证类
          """
          def authenticate(self, request):
              token = request._reqeust.GET.get('token')
              token_obj = models.UserToken.objects.filter(token=token).first()
              if not token_obj:
                  raise exceptions.AuthenticationFiled('用户认证失败')
              # 在restframework 内部会将这两个字段 赋值给request, 以供后续操作使用
              return (token_obj.user, token_obj)
    
          def anthentication_header(self,request):
              pass
    
    class OrderView(APIView):
           """
           订单业务
           """
           # restframework 自带功能能够验证 用户是否登录
           authentication = [Authtication,]
           def get(self, request, *args,**kwargs):
    
               ret={'code':1000,'msg':None,'data':None}
               try:
                   ret['data'] = ORDER_DICT
               except Exception as e:
                   pass
               return JsonResponse(ret)
    

      

     rest_framework源码执行流程:

    流程:
    0-----------
    authentication_class = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    1-----------
    def dispatch():
    	self.initial(request)
    2-----------
    def initial():
        self.perform_authenticate()
    3-----------
    def perform_authenticate():
    	reuqest.user
    4-----------
    @porperty
    def user():
        _authenticate()
    5-----------
    def _anthenticate():
    	循环认证类所有对象
    6-----------
    anthentication_class = [Authenticate,]
    7-----------
    Authenticate()  执行自定义的验证方法
    返回 user对象 和 token对象
    

      

     全局配置:

    REAT_FRAMEWORK = {
        'DEFAULT_AUTNENTICATINO_CLASSES': ['api.utils.auth.Authtication',]  
    }
    

      

    局部不使用:

    class OrderView(APIView):
           """
           订单业务
           """
           #  写一个空列表 就可以到达不用使用authentication_classes = [Authtication,] 达到不用登录验证的目的
           authentication_classes = []
           def get(self, request, *args,**kwargs):
               return JsonResponse(ret)
    

      

    配置匿名用户:

    REAT_FRAMEWORK = {
        # 推荐配置restframework的匿名用户为None
        "UNAUTHENTCATION_USER": None,    # request.user = None
    "UNAUTHENTICATION_TOKEN" None, # request.token = None }

    第三版: 

    继承BaseAuthentication

    from  rest_framework.authentication import BaseAuthentication
    class Authtication(BaseAuthentication):
          """
          用户登录认证类
          """
          def authenticate(self, request):
              token = request._reqeust.GET.get('token')
              token_obj = models.UserToken.objects.filter(token=token).first()
              if not token_obj:
                  raise exceptions.AuthenticationFiled('用户认证失败')
              # 在restframework 内部会将这两个字段 赋值给request, 以供后续操作使用
              return (token_obj.user, token_obj)
    
    

    1.  必须继承BaseAuthentication类

     2. 必须实现anthenticate方法

  • 相关阅读:
    无语的Filezilla
    服务无法启动集中帖
    FileZilla Server-Can’t access file错误解决方法
    CCNA2.0笔记_OSPF v3
    CCNA2.0笔记_OSPF v2
    <转>32位移植到64位 注意事项
    异步设备IO 《windows核心编程》第10章学习
    关于自己五年来做出的选择分析
    2015过年之前计划
    关于同一线程两次调用EnterCriticalSection的测试
  • 原文地址:https://www.cnblogs.com/kuku0223/p/11340540.html
Copyright © 2020-2023  润新知