DRF的版本、认证、权限
DRF的版本
版本控制是做什么用的, 我们为什么要用
首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~
当我们项目越来越更新~版本就越来越多~~我们不可能新的版本出了~以前旧的版本就不进行维护了~~~
那我们就需要对版本进行控制~~这个DRF也给我们提供了一些封装好的版本控制方法~~
版本控制怎么用
之前我们学视图的时候知道APIView,也知道APIView返回View中的view函数,然后调用的dispatch方法~
执行self.initial方法之前是各种赋值,包括request的重新封装赋值,下面是路由的分发,那我们看下这个方法都做了什么~~
我们可以看到,我们的version版本信息赋值给了 request.version 版本控制方案赋值给了 request.versioning_scheme~~
只是DRF默认的版本信息是None,我们需要重写一些配置,让request.version携带上我自定义的版本信息
request.versioning_scheme是实现版本控制的类的实例化对象~
详细用法
a. 基于url的get传参方式
如:/users?version=v1
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}
settings.py
from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^test/', TestView.as_view(),name='test'),
]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning class TestView(APIView):
versioning_class = QueryParameterVersioning def get(self, request, *args, **kwargs): # 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme) # 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容') views.py
views.py
b. 基于url的正则方式
如:/v1/users/
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}
settings.py
from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
] urls.py
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning class TestView(APIView):
versioning_class = URLPathVersioning def get(self, request, *args, **kwargs):
# 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme) # 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容') views.py
views.py
c. 基于 accept 请求头方式
如:Accept: application/json; version=1.0
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}
settings.py
from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^test/', TestView.as_view(), name='test'),
]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import AcceptHeaderVersioning class TestView(APIView):
versioning_class = AcceptHeaderVersioning def get(self, request, *args, **kwargs):
# 获取版本 HTTP_ACCEPT头
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme)
# 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
views.py
d. 基于主机名方法
如:v1.example.com
ALLOWED_HOSTS = ['*']
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}
settings.py
from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^test/', TestView.as_view(), name='test'),
]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import HostNameVersioning class TestView(APIView):
versioning_class = HostNameVersioning def get(self, request, *args, **kwargs):
# 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme)
# 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
views.py
e. 基于django路由系统的namespace
如:example.com/v1/users/
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}
settings.py
from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^v1/', ([
url(r'test/', TestView.as_view(), name='test'),
], None, 'v1')),
url(r'^v2/', ([
url(r'test/', TestView.as_view(), name='test'),
], None, 'v2')), ]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import NamespaceVersioning class TestView(APIView):
versioning_class = NamespaceVersioning def get(self, request, *args, **kwargs):
# 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme)
# 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
views.py
f. 全局使用
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version'
}
settings.py
DRF的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
"""
versioning模块
DRF的认证
上面讲版本的时候我们知道~在dispatch方法里~执行了initial方法~~那里初始化了我们的版本~~
如果我们细心我们能看到~版本的下面其实就是我们的认证,权限,频率组件了~~
我们先看看我们的认证组件~~
我们进去我们的认证看下~~
我们这个权限组件返回的是request.user,那我们这里的request是新的还是旧的呢~~
我们的initial是在我们request重新赋值之后的~所以这里的request是新的~也就是Request类实例对象~~
那这个user一定是一个静态方法~我们进去看看~~
很明显,有传参
我们通过上面基本可以知道我们的认证类一定要实现的方法~~以及返回值类型~~以及配置的参数authentication_classes~
DRF的权限
权限是什么
大家之前都应该听过权限~那么我们权限到底是做什么用的呢~~
大家都有博客~或者去一些论坛~一定知道管理员这个角色~
比如我们申请博客的时候~一定要向管理员申请~也就是说管理员会有一些特殊的权利~是我们没有的~~
这些对某件事情决策的范围和程度~我们叫做权限~~权限是我们在项目开发中非常常用到的~~
那我们看DRF框架给我们提供的权限组件都有哪些方法~~
权限组件源码
我们之前说过了DRF的版本和认证~也知道了权限和频率跟版本认证都是在initial方法里初始化的~~
其实我们版本,认证,权限,频率控制走的源码流程大致相同~~大家也可以在源码里看到~~
我们的权限类一定要有has_permission方法~否则就会抛出异常~~这也是框架给我提供的钩子~~
我们先看到在rest_framework.permissions这个文件中~存放了框架给我们提供的所有权限的方法~~
我这里就不带着大家详细去看每一个了~大家可以去浏览一下每个权限类~看看每个都是干嘛的~~
这里主要说下BasePermission 这个是我们写权限类继承的一个基础权限类~~~
认证权限的详细用法
用户url传入的token认证
from django.db import models # Create your models here. class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
token = models.UUIDField(null=True, blank=True)#随机字符串
CHOICES = ((1, "vip"), (2, "普通用户"), (3, "vvip"))
type = models.IntegerField(choices=CHOICES, default=2)
DRFDemo/AuthDemo/models.py
执行:makemigrations AuthDemo
migrate AuthDemo
from django.conf.urls import url, include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^book/', include("SerDemo.urls")),
url(r'^api/user/', include("AuthDemo.urls")),
url(r'^api/(?P<version>[v1|v2]+)/', include("VersionDemo.urls")),
]
DRFDemo/DRFDemo/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from .views import RegisterView, LoginView, TestView, PermissionView urlpatterns = [
url(r'^register', RegisterView.as_view()),
url(r'^login', LoginView.as_view()),
url(r'^test', TestView.as_view()),
url(r'^permission', PermissionView.as_view()), ]
DRFDemo/AuthDemo/urls.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
import uuid
from utils.auth import MyAuth
from utils.permission import MyPermission # Create your views here. class RegisterView(APIView):
def post(self, request):
name = request.data.get("name", "")
pwd = request.data.get("pwd", "")
if name and pwd:
User.objects.create(name=name, pwd=pwd)
return Response("注册成功")
return Response("用户名或密码不合法") class LoginView(APIView):
def post(self, request):
name = request.data.get("name", "")
pwd = request.data.get("pwd", "")
user_obj = User.objects.filter(name=name, pwd=pwd).first()
if user_obj:
# 登录成功 创建一个token并给前端返回
token = uuid.uuid4()
user_obj.token = token
user_obj.save()
return Response(token)
return Response("用户名或密码错误") class TestView(APIView):
authentication_classes = [MyAuth, ] def get(self, request):
print(request.user)
print(request.user.name)
print(request.auth)
return Response("登录后发送的数据") class PermissionView(APIView):
authentication_classes = [MyAuth, ]
permission_classes = [MyPermission, ] def get(self, request):
# 这个接口只能vip或者vvip访问
return Response("权限测试接口")
DRFDemo/AuthDemo/views.py
REST_FRAMEWORK = {
# "DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion",
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
'DEFAULT_VERSION': "v1",
'ALLOWED_VERSIONS': ["v1", "v2"],
'VERSION_PARAM': 'version',
# 配置认证类
# "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MyAuth", ]
}
DRFDemo/DRFDemo/settings.py
from rest_framework import permissions class MyPermission(permissions.BasePermission):
message = "请充VIP,999一年" def has_permission(self, request, view):
# 判断用户是否有权限
if request.user.type in [1, 3]:
return True
return False
DRFDemo/utils/permission.py
from django.db import models # Create your models here. class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
token = models.UUIDField(null=True, blank=True)
CHOICES = ((1, "vip"), (2, "普通用户"), (3, "vvip"))
type = models.IntegerField(choices=CHOICES, default=2)
DRFDemo/AuthDemo/models.py
DRF的版本、认证、权限的更多相关文章
- drf(请求封装/认证/权限/节流)
1.请求的封装 class HttpRequest(object): def __init__(self): pass @propery def GET(self): pass @propery de ...
- day74:drf:drf其他功能:认证/权限/限流/过滤/排序/分页/异常处理&自动生成接口文档
目录 1.django-admin 2.认证:Authentication 3.权限:Permissions 4.限流:Throttling 5.过滤:Filtering 6.排序:OrderingF ...
- DRF 版本 认证
DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢大家都知道我们开发项目是有多个版本的 当我们项目越来越更新~版本就越来越多我们不可能新的版本出了~以前旧的版本 ...
- DRF的版本和认证
DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们项目越来越更新~版本就越来越多~~我们不可能新的版本出了~ ...
- drf框架中认证与权限工作原理及设置
0909自我总结 drf框架中认证与权限工作原理及设置 一.概述 1.认证 工作原理 返回None => 游客 返回user,auth => 登录用户 抛出异常 => 非法用户 前台 ...
- 实战-DRF快速写接口(认证权限频率)
实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...
- Restful API学习Day4 - DRF版本控制和认证
参考文档: Django REST framework基础:版本控制 Django REST framework基础:认证.权限.限制 为什么要有版本? 某些客户端 使用低版本只维护不开发新功能 v1 ...
- Kafka认证权限配置(动态添加用户)
之前写过一篇Kafka ACL使用实战,里面演示了如何配置SASL PLAINTEXT + ACL来为Kafka集群提供认证/权限安全保障,但有一个问题经常被问到:这种方案下是否支持动态增加/移除认证 ...
- 【DRF框架】认证组件
DRF框架的认证组件 核心代码: self.perform_authentication(request) 框架自带模块: from rest_framework import a ...
随机推荐
- C语言 · 图形输出
算法提高 图形输出 时间限制:1.0s 内存限制:512.0MB 编写一程序,在屏幕上输出如下内容: X | X | X ---+---+--- | | ---+---+--- O ...
- Linux samba 服务的配置
今天有个学生问我 samba 服务怎么配置,所以晚上特意研究一下怎么配置这个服务. 过程如下: sudo apt-get install samba samba-common // 安装 samba ...
- span和img标签对齐
html代码 <li> <span class="left_item">在线</span> <img class="right_ ...
- gt811 driver
#include <linux/module.h> #include <linux/i2c.h> #include <linux/platform_device.h> ...
- cacati的安装
一.安装rrdtool软件包 yum install -y cairo-devel libxml2-devel pango-devel pango libpng-devel freetype free ...
- 关于ajax跨域的一些说说
跨域:跨当然是跨过去,域当然是别的服务器 (说白点就是去别服务器上取东西) 只要协议.域名.端口有任何一个不同,都被当作是不同的域 ajax 是一种请求响应无刷新技术(xmlhttqrequest对象 ...
- 数据库 proc编程七
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stri ...
- 验证:record项元的多少影响修改速度。
验证erlang官网提供的思想:record的修改是复制. -module (test_record). -record (record_5,{ aa1 = 0, aa2 = 0, aa3 = 0, ...
- 查看linux系统外网ip命令
终端中输入 curl ipinfo.io 或者 curl ifconfig.me 即可通过IP地址检测网站提供的api获得取本机的外网IP,或者以 JSON 格式返回全部结果.
- 使用webdriverwait封装查找元素方法
对于selenium原生的查找元素方法进行封装,在timeout规定时间内循环查找页面上有没有某个元素 这样封装的好处: 1.可以有效提高查找元素的效率,避免元素还没加载完就抛异常 2.相对于time ...