zoukankan      html  css  js  c++  java
  • 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方法

  • 相关阅读:
    rs
    stm32f767 usoc3
    stm32f767 RTT 日志
    stm32f767 标准库 工程模板
    stm32f767 HAL 工程模板
    docker tab 补全 linux tab 补全
    docker anconda 依赖 下载 不了
    docker run 常用 指令
    linux scp 命令
    Dockerfile 常用参数说明
  • 原文地址:https://www.cnblogs.com/kuku0223/p/11340540.html
Copyright © 2011-2022 走看看