DRF三大认证:认证、权限、频率
登录接口
class User(ModelViewSet):
queryset = models.User.objects.all()
serializer_class = UserSerializer
@action(methods=['POST'], detail=False)
def login(self, request):
name = request.data.get('name')
password = request.data.get('password')
user_obj = models.User.objects.filter(name=name, password=password).first()
if user_obj:
token = str(uuid.uuid4())
user_token = models.UserToken.objects.update_or_create(defaults={'token':token},user=user_obj)
print(user_token)
return Response({'code': 100, 'msg': '登录成功', 'token': token})
else:
return Response({'code': 101, 'msg': '用户名或者密码错误'})
-
认证
-第一步:写一个认证类,继承BaseAuthentication,重写authenticate 方法
-第二步:在 authenticate 方法中判断用户是否登录(取出用户携带的token,去判断)
-第三步:如果认证通过,返回两个值,如果认证不通过抛异常
-
-第四步:把写的认证类,配置在视图类中(跟请求和响应的配置一样),全局配置
-鸭子类型:不需要显示的继承某个类,只要类中有共同的属性和方法,我们就是同一类
非鸭子类型:比如 狗和猫 必须继承 动物类 他俩才是动物类
1.1认证的使用
from rest_framework.authentication import BaseAuthentication
from .models import UserToken
from rest_framework.exceptions import AuthenticationFailed
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_TOKEN')
user_token = UserToken.objects.filter(token=token).first()
print(user_token)
if user_token:
return user_token.user, token
else:
raise AuthenticationFailed('没有登录')
1.2全局配置和局部配置
class BookView(ModelViewSet):
authentication_classes = [LoginAuth]
queryset = models.Book2.objects.all()
serializer_class = BookSerializer
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'app01.auth.LoginAuth'
],
}
-
权限
1:写一个权限类,继承BasePermission,重写has_permission 方法
2:在 重写has_permission 方法中判断用户是否有权限(request.user.user_type)认证后才可以知道有什么权限
3:如果有权限,返回True,如果返回False
4:把写的权限类,配置在视图类中(跟请求和响应的配置一样),全局配置
2.1权限的使用
from rest_framework.permissions import BasePermission
class CommonUser(BasePermission):
def has_permission(self, request, view):
if request.user.user_type in [1, 2]:
return True
else:
return False
class Administrator(BasePermission):
def has_permission(self, request, view):
if request.user.user_type in [2]:
return True
else:
return False
2.2权限的局部配置和全局配置
全局配置
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.auth.CommonUser',
'app01.auth.Administrator',
],
}
局部配置
permission_classes=[权限类名]
那么 登录接口权限设置应该为空 这个接口就是谁都可以访问 登陆之后才可以确认是什么权限
图书接口 所有人都可以访问 应该也设置为空
出版社 设置成自己的权限
-
频率
-第一步:写一个类,继承SimpleRateThrottle,重写get_cache_key
-第二步:get_cache_key返回什么就以什么做限制,必须写类属性 scope='字符串'限制了
-第三步:配置文件中配置
'DEFAULT_THROTTLE_RATES': {
'字符串': '3/m',
},
-第四步:局部使用和全局使用
3.1频率的使用
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
class MyThrottling(SimpleRateThrottle):
scope = 'ip_1_3'
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR')
'DEFAULT_THROTTLE_RATES': {
'ip_1_3': '3/m',
},
3.2频率的全局配置和局部配置
'DEFAULT_THROTTLE_CLASSES': ['app01.auth.MyThrottling'],
throttle_classes = [MyThrottling]
权限源码
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
def check_permissions(self, request):
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
视图基类、视图子类、视图扩展类
两个视图基类 还需要写get post 等方法
APIView
GenericAPIView
定义了queryset 和 serializer_class lookup_field 三个属性 第三个可以不写
定义了 get_queryset 和 get_object 和 get_serializer 三个方法
五个视图拓展类 from rest_framework.mixins import
UpdateModelMixin,