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方法

posted @ 2019-08-12 15:41  划得戳  阅读(361)  评论(0编辑  收藏  举报