DRF之版本控制、认证和权限组件

一、版本控制组件

1、为什么要使用版本控制

首先我们开发项目是有多个版本的
当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了
像bootstrap有2、3、4版本的,每个版本都有它对应的url,https://v2.bootcss.com/ 、 https://v3.bootcss.com/
这就需要我们对版本进行控制,这个DRF也给我们提供了一些封装好的版本控制方法

2、原理

1.
在DRF框架中,它默认帮我们设置了版本信息在request.versionrequest.versioning_scheme中,
只是DRF默认的版本信息是None,我们需要重写一些配置,让request.version携带上我自定义的版本信息
request.versioning_scheme是实现版本控制的类的实例化对象

2.

CBV视图函数都是首先会去执行as_view方法的,as_view会找到路由的分发方法dispatch,在真正分发之前会执行initial方法

3、使用

0. 在哪里取版本信息
我们的版本类必须重写determine_version这个方法,request.version就是拿它的返回值
在视图中就可以使用request.version取到版本信息

1. 新建一个py文件
我建在utils文件夹下的version.py
在version.py下重写一个MyVersion类
注意:必须重写determine_version这个方法,因为request.version就是拿它的返回值
class MyVersion(object):
    def determine_version(self,request, *args, **kwargs):
        version = request.query_params.get("version", "v1")
        return version

2. 去项目的settings配置
# 覆盖DRF原本的配置DEFAULT_VERSIONING_CLASS,让它的值指向我们写的那个类

REST_FRAMEWORK = {
    ‘DEFAULT_VERSIONING_CLASS‘: ‘utils.version.MyVersion‘
}

3. 在视图中使用
class VersionView(APIView):
    def get(self, request):
        print(request.version)
        print(request.versioning_scheme)
        if request.version == ‘v1‘:
            return Response("v1版本")
        elif request.version == ‘v2‘:
            return Response(‘v2版本‘)
        return Response(‘不存在的版本‘)

4、DRF的versioning模块

1. 在这里模块内给我们配置了各种获取版本的类

2. versioning模块

# 基础类
class BaseVersioning(object):
    default_version = api_settings.DEFAULT_VERSION
    allowed_versions = api_settings.ALLOWED_VERSIONS
    version_param = api_settings.VERSION_PARAM

    def determine_version(self, request, *args, **kwargs):
        msg = ‘{cls}.determine_version() must be implemented.‘
        raise NotImplementedError(msg.format(
            cls=self.__class__.__name__
        ))

    def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
        return _reverse(viewname, args, kwargs, request, format, **extra)

    def is_allowed_version(self, version):
        if not self.allowed_versions:
            return True
        return ((version is not None and version == self.default_version) or
                (version in self.allowed_versions))

# 在请求头中携带版本信息
class AcceptHeaderVersioning(BaseVersioning):
    """
    GET /something/ HTTP/1.1
    Host: example.com
    Accept: application/json; version=1.0
    """

# 在URL中携带版本信息
class URLPathVersioning(BaseVersioning):
    ‘‘‘
    urlpatterns = [
        url(r‘^(?P<version>[v1|v2]+)/users/$‘, users_list, name=‘users-list‘),
        url(r‘^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$‘, users_detail, name=‘users-detail‘)
    ]
    ‘‘‘

# 在namespace中携带版本信息
class NamespaceVersioning(BaseVersioning):
    ‘‘‘
    # users/urls.py
    urlpatterns = [
        url(r‘^/users/$‘, users_list, name=‘users-list‘),
        url(r‘^/users/(?P<pk>[0-9]+)/$‘, users_detail, name=‘users-detail‘)
    ]

    # urls.py
    urlpatterns = [
        url(r‘^v1/‘, include(‘users.urls‘, namespace=‘v1‘)),
        url(r‘^v2/‘, include(‘users.urls‘, namespace=‘v2‘))
    ]
    ‘‘‘

# 在域名中携带版本信息
class HostNameVersioning(BaseVersioning):
    """
    GET /something/ HTTP/1.1
    Host: v1.example.com
    Accept: application/json
    """

# 在参数中携带版本信息
class QueryParameterVersioning(BaseVersioning):
    """
    GET /something/?version=0.1 HTTP/1.1
    Host: example.com
    Accept: application/json
    """

version模块的类


3. 基础类的三个配置
REST_FRAMEWORK = {
    ‘DEFAULT_VERSIONING_CLASS‘: ‘utils.version.MyVersion‘,
    # 默认版本
    ‘default_version‘: ‘v1‘,
    # 可用版本
    ‘allowed_versions‘: [‘v1‘, ‘v2‘],
    # 参数
    ‘version_param‘: ‘version‘,
}
4. 使用DRF的版本控制
方法一
1. 在utils文件夹下的version.py继承versioning的类

from rest_framework import versioning

class MyVersion(versioning.URLPathVersioning):
    pass

2. urls.py
urlpatterns = [
    # url(r‘^version_demo/‘, views.VersionView.as_view()),
    url(r‘^(?P<version>[v1|v2]+)/version_demo/‘, views.VersionView.as_view()),
]

3. settings.py
REST_FRAMEWORK = {
    ‘DEFAULT_VERSIONING_CLASS‘: ‘utils.version.MyVersion‘,
    # 默认版本
    ‘default_version‘: ‘v1‘,
    # 可用版本
    ‘allowed_versions‘: [‘v1‘, ‘v2‘],
    # 参数
    ‘version_param‘: ‘version‘,
}

4.在视图中使用需要接收参数version
class VersionView(APIView):
    def get(self, request, version):
        print(request.version)
        print(request.versioning_scheme)
        if request.version == ‘v1‘:
            return Response("v1版本")
        elif request.version == ‘v2‘:
            return Response(‘v2版本‘)
        return Response(‘不存在的版本‘)

5. 在浏览器中
可以输入:
    v1/version_demo/
    v2/version_demo/

方法二
其他步骤基本一样,只是我们在配置的时候直接指定某个类
1. urls.py
urlpatterns = [
    # url(r‘^version_demo/‘, views.VersionView.as_view()),
    url(r‘^(?P<version>[v1|v2]+)/version_demo/‘, views.VersionView.as_view()),
]

2. settings.py
REST_FRAMEWORK = {
    ‘DEFAULT_VERSIONING_CLASS‘: ‘rest_framework.versioning.URLPathVersioning‘,  # 指定URLPathVersioning这个类
    # 默认版本
    ‘default_version‘: ‘v1‘,
    # 可用版本
    ‘allowed_versions‘: [‘v1‘, ‘v2‘],
    # 参数
    ‘version_param‘: ‘version‘,
}

二、认证

1、为什么要认证

我们可以在网站上登录,然后可以有个人中心,对自己信息就行修改
但是我们每次给服务器发请求,由于Http的无状态,导致我们每次都是新的请求
那么服务端需要对每次来的请求进行认证,看用户是否登录,以及登录用户是谁
那么我们服务器对每个请求进行认证的时候,不可能在每个视图函数中都写认证
一定是把认证逻辑抽离出来,以前我们可能会加装饰器,或者中间件,DRF框架也有它的认证

2、原理

在前端进行登录的时候,用户名和密码输入正确后,后端根据用户名和密码拿到这个用户的一些信息(用户名,性别等),
把这些信息加密后生成一个随机字符串token返回给前端,
前端下次请求再来的时候,带上这个随机字符串,后端根据自己的解密算法再算出来,实现认证。

3、token认证

0. 在哪里取认证的信息
我们的认证类必须重写authenticate这个方法,返回值是元组
第一个值赋值给了request.user, 第二个赋值给request.auth
在视图中就可以使用request.user和request.auth取到认证的信息

1. models.py
class User(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
    # 用UUID字符串存随机字符串
    token = models.UUIDField(null=True, blank=True)
    CHOICES = ((1, "vip"), (2, "普通用户"), (3, "vvip"))

2. settings配置
# 跟版本一样,覆盖原本的配置,使用自己的配置
REST_FRAMEWORK = {
    # 配置认证类
    # 这样配是全局,所有路由都要认证
    ‘DEFAULT_AUTHENTICATION_CLASSES‘:[‘utils.auth.MyAuth‘, ]
}

3. utils/auth.py
from rest_framework import authentication
from AuthDemo.models import User
from rest_framework.exceptions import AuthenticationFailed

class MyAuth(authentication.BaseAuthentication):
    # 必须重写authenticate这个方法,返回值是元组
    # 第一个值赋值给了request.user, 第二个赋值给request.auth
    def authenticate(self, request):
        # 获取前端携带的token,看token是否合法
        token = request.query_params.get("token", "")
        if not token:
            raise AuthenticationFailed("没有携带token")
        user_obj = User.objects.filter(token=token).first()
        # 返回需要的信息
        if user_obj:
            return (user_obj, token)
        # 验证不通过,抛出异常
        raise AuthenticationFailed("token不合法")

4. 视图
class TestView(APIView):
    def get(self, request):
        print(request.user)
        print(request.auth)
        return Response("登陆后发送的数据")

5. 局部配置
1. 如果只是某些路由需要认证,那么可以局部设置认证,包括版本也可以局部认证

2. 把settings的配置注释掉

3. 在需要认证的视图中声明
from utils.auth import MyAuth

class TestView(APIView):
    authentication_classes = [MyAuth, ]  # 局部配置认证组件
    # versioning_class = []  # 局部配置版本组件
    def get(self, request):
        print(request.user)
        print(request.auth)
        return Response("登陆后发送的数据")

原文地址:https://www.cnblogs.com/Zzbj/p/10112019.html

时间: 2024-11-10 18:37:20

DRF之版本控制、认证和权限组件的相关文章

DRF 版本、认证、权限、限制、解析器和渲染器

目录 一.DRF之版本控制 为什么要有版本控制? DRF提供的版本控制方案 版本的使用 全局配置 局部配置(使用较少) 二.DRF之认证 内置的认证 步骤 三.DRF之权限 1.自定义一个权限类 2.权限 局部配置 3.权限 全局配置 四.DRF之限制 1.使用自定义限制类 1.1自定义一个限制类 1.2限制 局部配置 1.3限制 全局配置 2.使用内置限制类 2.1定义内置限制类 2.2全局配置 五.DRF之分页 1.为什么要使用分页 2.DRF使用分页器 2.1分页模式 2.2全局配置 2.

Drf03 / drf版本、认证、权限

目录 Drf03 / drf版本.认证.权限 回顾和补充 今日概要 今日详细 1.请求的封装 2.版本 3.认证(面试) 作业:将认证的功能添加到呼啦圈中. Drf03 / drf版本.认证.权限 回顾和补充 restful规范 1. 建议用https代替http 2. 在URL中体现api,添加api标识 https://www.cnblogs.com/xwgblog/p/11812244.html # 错误 https://www.cnblogs.com/api/xwgblog/p/1181

rest_framework组件之认证,权限,访问频率

共用的models 1 from django.db import models 2 3 4 # Create your models here. 5 6 7 class User(models.Model): 8 username = models.CharField(max_length=32) 9 password = models.CharField(max_length=32) 10 user_type = models.IntegerField(choices=((1, '超级用户'

Django中rest_framework的认证组件,权限组件,频率组件,序列化组件的最简化版接口

url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.Login.as_view()), # Book表 url(r'^books/$',views.BookHandle.as_view({ 'get':'list', 'post':'create' })), url(r'^books/(?P<pk>\d+)/',views.BookHandle.as_view({ 'get':'retrieve

DRF框架中其他功能:认证、权限、限流

定义视图时,只要视图继承了APIView或其子类,就可以使用DRF框架的认证.权限和限流功能. 当客户端访问API接口时,DRF框架在调用对应的API接口之前,会依次进行认证.权限和限流的操作. 认证Authentication 权限Permissions 限流Throttling 原文地址:https://www.cnblogs.com/oklizz/p/11290731.html

认证、权限、频率、自定义签发token-多方式登录

目录 三大认证流程图 路由配置 认证组件 权限组件 自定义权限类 配置drf自带的权限类 drf-jwt 签发token源码分析 多方式登录 签发token VIP用户认证权限例子 频率组件 自定义频率类 三大认证流程图 路由配置 在应用下新建文件router.py # router.py from rest_framework.routers import Route, DynamicRoute, SimpleRouter as DRFSimpleRouter class SimpleRout

drf认证组件、权限组件、jwt认证、签发、jwt框架使用

目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书资源接口 urls.py views.py serializers.py 五.认证组件 重点 自定义认证类 六.权限组件 重点 自定义权限类 七.jwt认证示意图 八. jwt认证算法:签发与校验 签发:根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token 校验:根据客户端带toke

drf框架 8 系统权限类使用 用户中心信息自查 token刷新机制 认证组件项目使用:多方式登录 权限组件项目使用:vip用户权限 频率组件 异常组件项目使用

系统权限类使用 图书接口:游客只读,用户可增删改查权限使用 from rest_framework.permissions import IsAuthenticatedOrReadOnly class BookViewSet(ModelViewSet): # 游客只读,用户可增删改查 permission_classes = [IsAuthenticatedOrReadOnly] queryset = models.Book.objects.all() serializer_class = se

drf之组件(认证、权限、排序、过滤、分页等)和xadmin、coreapi

认证Authentication 可以在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', # 基本认证 'rest_framework.authentication.SessionAuthentication', # session认证 ) } 也可以在每个视图中通过设置authentication