首页 > 技术文章 > Django Rest framework 框架之认证使用和源码执行流程

zhangrenguo 2019-02-24 19:48 原文

用这个框架需要先安装:

pip3 install djangorestframework

 

如果写了一个CBV的东西,继承了View。

# 继承Django里面View
class APIView(View):
    pass

# 订单View继承了APIView,相当于这个订单里面的功能就更多了。
class OrderView(APIView):
    pass

 

 

restframework

from rest_framework.views import APIView

 

这个APIView继承View

 

这个View是Django里面的View

 

APIView多了些这么多功能

 

 CBV的流程,URL-当前试图类-父类---dispatch

 

 

 

怎么加工request:

丰富了request一些功能,

authenticators是怎么来的---->调用self.get_authenticators(),self.get_authenticators()又是什么?

self.get_authenticators()应该先从,当前视图的类找,因为它里面传过去的self都是当前视图的类的对象。

没有才去父类找。它返回了个列表,列表里面有个列表生成式,如果self.authentication_classes是一个列表[Foo,Bar]里面表示两个类。对每个类进行了实例化。所以谁调用get_authenticators

返回的应该是[Foo,Bar]这个类的对象。

所以self.get_authenticators()是[Foo(),Bar()]

而self.authentication_classes是配置文件。是APIView里面的,从当前自己视图类找不到才去父类找,如果自己找到了呢?

 

如果自己找到了呢?

 

----

封装request

认证

实现认证

request.user

获取认证对象进行一步一步的认证

----

 

 

 

 

 

 

from django.views import View
from rest_framework.views import APIView
from rest_framework.authentication import BasicAuthentication
from rest_framework import exceptions
from rest_framework.request import Request

class MyAuthentication(object):
    def authenticate(self,request):
        token = request._request.GET.get('token')  #如果token不存在表示没有传没有登录抛个异常
        if not token:
            raise exceptions.AuthenticationFailed('您没有登录')

        return ('zrg',None)


    def authenticate_header(self,val):
        pass

 

class DogView(APIView):
    # cbv请求进来 URL---> view方法 ----->dispatch方法 做路由分发

    authentication_classes = [MyAuthentication,]    #表示获取到的是BasicAuthentication这个类的一个对象


    def get(self,request,*args,**kwargs):
        # self.dispatch
        # print(request)   #这个request已经不是Django原来的request了。而是调用了self.initialize_request(request, *args, **kwargs)这个方法加工之后的request
        # 就是Django rest framework之后的request,这里面还包含原生的request,

        # return Request(
        #     request,
        #     parsers=self.get_parsers(),
        #     authenticators=self.get_authenticators(),
        #     negotiator=self.get_content_negotiator(),
        #     parser_context=parser_context
        # )
        response = {
            'code':1000,
            'msg':'successful'
        }

        return HttpResponse(json.dumps(response),status=202)

    def post(self, request, *args, **kwargs):

        return HttpResponse('创建dog')

 

 

 

认证:

如果只是用只需要写一个类,获取用户名或密码去数据库校验,如果有继续往后走,没有就报异常。

如果想应用这个认证,在试图里要加上,以后不管URL发什么请求都必须认证成功才可以往下走。

print(request.user)这个user就是‘zrg'---->返回的元组的第一个值。

 

源码流程:

入口就是dispatch。

 

 

 

 

 

 

 

 

 

 

Django Rest framework 框架之认证

 含restframework框架的生命周期是:请求进来---》dispatch才触发。

需求:如果用Django写的接口,这个接口需要控制有的人能访问有的人不能访问!通过什么来控制?

有些API需要用户登录成功才能访问,有些无需登录就能访问。

 

2.用户登录返回token并保存到数据库,以后他再来访问其他需要登陆之后才能访问的页面就必须通过我的认证才能通过。

from django.shortcuts import render
from django.http import JsonResponse

# Create your views here.



from rest_framework.views import APIView
from api import models


def md5(user):
    import hashlib
    import time

    current_time = str(time.time())

    m = hashlib.md5(bytes(user,encoding='utf-8'))
    m.update(bytes(current_time,encoding='utf-8'))

    return m.hexdigest()



class AuthView(APIView):

    def post(self,request,*args,**kwargs):

        response = {
            'code':1000,
            'msg':'None'
        }

        try:
            user = request._request.POST.get('username')
            pwd = request._request.POST.get('password')

            obj = models.UserInfo.objects.filter(username=user,password=pwd).first()

            if not obj:
                response['code']=1001
                response['msg']='用户名或密码错误'

            # 为登录用户创建token(随机字符串,md5+时间戳+当前时间+当前用户名)
            token = md5(user)
            # 存在更新,不存在就创建
            models.UserToken.objects.update_or_create(user=obj,defaults={'token':token})
            # 返回token
            response['token']=token
            
        except Exception as e:
            response['code']=1002
            response['msg']='请求异常'

        return JsonResponse(response)

 

from api import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/v1/auth/$', views.AuthView.as_view()),
]

 

 1.创建了两张表。一张存用户信息,一张存用户登录成功之后的token。在视图里面我们去用户表根据他提供的用户名跟密码,为他生成token,生成token不仅给他我们还在数据库保存了一份。

 

from django.db import models

# Create your models here.

class UserInfo(models.Model):
    user_type_choice = (
        (1,'普通用户'),
        (2,'VIP'),
        (3,'SVIP'),


    )
    user_type = models.IntegerField(choices=user_type_choice)
    username = models.CharField(max_length=32,unique=True)
    password = models.CharField(max_length=32)



class UserToken(models.Model):
    user = models.OneToOneField(to='UserInfo')
    token = models.CharField(max_length=64)
    #可以加时间加次数表示这段token最长用多久最多可以用几次。。。。

 

 

登陆过的人才能看。怎么验证他已经登录过了?---token。

创建一个类,把这个类加到我的类中,表示我们这个类可以应用认证规则了。

restframework还支持全局配置。

 

 

 

 

 

 

 

 

 

 

Django Rest framework 框架之权限组件

只要能通过认证,就在request里面赋值。比如说有不同的用户类型,就有权限之分。

权限怎么划分?在哪里做?

问题:不同视图不同权限可以访问。

 

基本使用:

 

 

源码流程:

 

梳理:

 

 

 

Django Rest framework 框架之节流(用户的访问频率控制)

 某个用户它访问频率,一分钟最多访问6次,超过之后提示还有多少秒可以再次访问。

需求分析:

 

基本使用:

 

 

源码流程:

 

 

内置的

 

 

 

 

 

 

Django Rest framework 框架之版本处理

 

推荐阅读