DRF框架之认证与权限
认证与权限
Django REST Framework (DRF)提供了一系列的认证与权限功能来保护Web API不被未授权用户访问或滥用。
认证(Authentication)
在DRF中,认证是指验证用户身份的过程,如果用户提供的凭据(例如用户名和密码)通过验证,则认为该用户是经过认证的用户。
DRF支持多种认证方式:
SessionAuthentication: 基于django的session机制实现的认证方式,在使用时需要先登录获取session id,然后发送请求时携带该session id
BasicAuthentication: 基于HTTP Basic Authentication协议实现的认证方式,用户需要在请求头中携带base64编码后的用户名和密码
TokenAuthentication: 基于Token的认证方式,用户需要先通过用户名和密码获取一个Token,然后在每次请求时携带该Token进行认证
JSONWebTokenAuthentication: 基于JSON Web Token(JWT)的认证方式,具有无状态、可扩展性等优点
DRF框架默认在rest_framework.settings文件中进行了全局认证方案的设置
DEFAULTS = {
'DEFAULT_AUTHENTICATION_CLASSES': (
# sesssion认证
'rest_framework.authentication.SessionAuthentication',
# 基本认证
'rest_framework.authentication.BasicAuthentication'
)
}
权限(Permission)
在DRF中,权限是指控制用户对API资源访问的能力。权限控制可以限制用户对于视图API的访问和对于具体数据对象的访问。
1.在执行视图的dispatch()方法前,会先进行视图访问权限的判断
2.在通过get_object()获取具体对象时,会进行对象访问权限的判断
DRF提供了多种预设的权限类:
IsAuthenticated: 仅允许已经认证的用户访问
AllowAny: 允许任何人访问
IsAdminUser: 仅允许管理员用户访问
IsAuthenticatedOrReadOnly: 对于未认证的用户只允许进行读取操作,已认证用户可以执行任意操作
DjangoModelPermissions: 基于Django模型的权限控制,与Django admin中的权限控制类似
DjangoObjectPermissions: 基于Django模型对象的权限控制
也可以自定义权限类,实现更加灵活的权限控制。
DRF框架默认在rest_framework.settings文件中进行了全局权限控制方案的设置
DEFAULTS = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny', # 允许所有人
)
}
认证和权限的使用
创建用户用于验证
使用Django自带用户认证系统,创建一个用户,用于登录验证
import os
from django.test import TestCase
from django.contrib.auth.models import User
if not os.environ.get('DJANGO_SETTINGS_MODULE'):
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo_mall.settings')
import django
django.setup()
class MyTest(TestCase):
User.objects.create_user(username='admin', password='admin')
配置认证与权限(全局)
可以在DRF项目的settings.py文件中修改DRF框架的全局认证方案与全局权限控制方案
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
# 基本认证
'rest_framework.authentication.BasicAuthentication',
# sesssion认证
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
# 将全局权限控制方案设置为仅允许认证用户访问
'rest_framework.permissions.IsAuthenticated',
)
}
认证与权限控制配置好后,访问某URL将出现BasicAuthentication认证框。
认证成功:
认证失败:
视图指定认证与权限(局部)
可以在每个视图中通过设置authentication_classess
属性与permission_classes
属性设置视图的认证与权限方案
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class TestView(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# 指定当前视图的认证方案,不使用全局认证方案
authentication_classess = [BasicAuthentication, SessionAuthentication]
# 指定当前视图的权限控制方案,不使用全局权限控制方案
permission_classes = [IsAuthenticated]
配合权限,如果认证失败会有两种可能的返回值:
401 Unauthorized 未认证
403 Permission Denied 权限被禁止
自定义权限
概述
自定义权限控制类,需继承rest_framework.permissions.BasePermission
父类,并实现以下两个任何一个方法或全部方法。
.has_permission(self, request, view) :
判断对使用此权限类的视图是否有访问权限, request表示请求对象,view表示当前视图对象,必须返回一个布尔值,指示请求是否被允许。
.has_object_permission(self, request, view, obj):
判断使用此权限类视图某个数据对象是否有访问权限, request表示请求, view表示当前视图, obj为数据对象
两者区别:
如果要在全局范围内控制某些操作,则使用has_permission()方法。如果要在单个对象级别控制某些操作,则使用has_object_permission()方法。
注意:
如果请求被授予访问权限,方法应该返回True,否则返回False。仅当视图级has_permission检查已通过时,才会调用实例级has_object_permission方法。
创建自定义权限类
创建一个名为MyPermission的自定义权限类。该类继承DRF的BasePermission,并覆盖了其中的has_permission方法与has_object_permission方法。
from rest_framework.permissions import BasePermission
class MyPermission(BasePermission):
# 判断对使用此权限类的视图是否有访问权限
def has_permission(self, request, view):
# 任何用户对使用此权限类的视图都没有访问权限
return True
# 判断对使用此权限类视图某个数据对象是否有访问权限
def has_object_permission(self, request, view, obj):
# 对id为1,3的数据对象有访问权限
print(obj)
if obj.id in (1, 3):
return True
return False
使用自定义权限类
class TestView(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# 指定当前视图的认证方案,不使用全局认证方案
# authentication_classess = [BasicAuthentication, SessionAuthentication]
# 指定当前视图的权限控制方案,不使用全局权限控制方案
# permission_classes = [IsAuthenticated]
# 使用自定义的权限控制类
permission_classes = [MyPermission]
使用TokenAuthentication身份验证
在Django REST Framework中,可以使用TokenAuthentication来进行身份验证。TokenAuthentication是基于令牌的身份验证方式,通过向每个用户分配唯一的令牌来识别用户。当用户发送请求时,他们需要在请求头中包含该令牌以进行身份验证。
配置
在settings.py文件中配置
在INSTALLED_APPS中添加rest_framework.authtoken应用程序
INSTALLED_APPS = [
'rest_framework.authtoken',
]
在REST_FRAMEWORK中配置认证与权限类
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
# 设置使用JSON渲染器
'rest_framework.renderers.JSONRenderer',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
# 使用TokenAuthentication认证
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
# 使用IsAuthenticated权限类确保已登录用户才能访问API
'rest_framework.permissions.IsAuthenticated',
],
}
执行数据库迁移
1.在项目根目录下执行命令来生成迁移文件
python manage.py makemigrations
2.运行命令来应用最新的数据库迁移
python manage.py migrate
3.如果曾经手动删除authtoken_token
表,请将该表重新创建。通过运行命令来创建该表
python manage.py migrate rest_framework.authtoken
注意: 在进行数据库迁移之前,请务必备份数据库以避免数据丢失。
创建一个认证令牌
先创建一个john用户对象,然后获取john用户对象,使用该对象创建一个Token对象。最后就可以使用这个Token来进行API请求的认证。
# 设置Django运行所依赖的环境变量
import os
from django.test import TestCase
if not os.environ.get('DJANGO_SETTINGS_MODULE'):
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_demo.settings')
# 让Django进行一次初始化
import django
django.setup()
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
class MyTest(TestCase):
# User.objects.create(username='john', password='password')
user = User.objects.get(username='john')
token = Token.objects.create(user=user)
print(token)
创建视图
创建一个MyView视图,然后添加身份验证
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class MyView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({'username': request.user.username})
配置路由
urlpatterns = [
re_path(r'^test/$', views.MyView.as_view(), name='test'),
]
测试
发送请求,Django REST Framework将检查请求头中是否包含有效的令牌,如果是,则允许该请求。
无效的令牌,拦截。
{
"detail": "Authentication credentials were not provided."
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136834.html