认证 权限 频率控制 组件

rest_framework组件

认证组件

局部认证

在需要认证的视图类里加上authentication_classes = [认证组件1类名,认证组件2类名....]

注意:这个类要放在单独的py文件中,(如果放在view中,全局配置无法使用)

验证通过(布尔值),可以返回两个值,一个给了request.user,一个给了request.auth

choice的用法:
-拿出数字对应的中文:get_字段名_dispaly()

示例如下:

seralizers.py

from rest_framework import serializers
from app01 import models
 
class PublishSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = '__all__'

auth.py

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from app01 import models
 
class TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        '''authenticate'''
        # 验证条件根据需求设置(此示例为需要有token值)
        token = request.GET.get('token')
        token_obj = models.Token.objects.filter(token=token).first()
        if not token_obj:
            # 如果验证失败,需抛出AuthenticationFailed异常
            raise exceptions.AuthenticationFailed("验证失败!")
        else:
            user = token_obj.user
            # 如果验证成功,需要返回一个元组,分别是用户以及验证类的实例对象,然后源码内会赋值给request.user和request.auth
            return user,token_obj

views.py

def get_random(name):
    import hashlib
    import time
    md=hashlib.md5()
    md.update(bytes(str(time.time()),encoding='utf-8'))
    md.update(bytes(name,encoding='utf-8'))
    return md.hexdigest()
class Login(APIView):
    def post(self,reuquest):
        back_msg={'status':1001,'msg':None}
        try:
            name=reuquest.data.get('name')
            pwd=reuquest.data.get('pwd')
            user=models.User.objects.filter(username=name,password=pwd).first()
            if user:
                token=get_random(name)
                                                                                      models.UserToken.objects.update_or_create
                    (user=user,defaults={'token':token})
                back_msg['status']='1000'
                back_msg['msg']='登录成功'
                back_msg['token']=token
            else:
                back_msg['msg'] = '用户名或密码错误'
        except Exception as e:
            back_msg['msg']=str(e)
        return Response(back_msg)


class Course(APIView):
    authentication_classes = [TokenAuth, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

全局认证

在settings.py中进行如下配置

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.TokenAuth",]
}

这样配置之后,每个视图类都要经过认证成功之后才能执行下一步,

如果有某些方法不需要认证,如login函数,则需要在该视图中单独加入一个配置属性:

authentication_classes = [] #将自身的认证类置空

权限认证

局部认证

permission.py

from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
    message = '不是超级用户,查看不了'
    def has_permission(self, request, view):
        # user_type = request.user.get_user_type_display()
        # if user_type == '超级用户':
        user_type = request.user.user_type
        print(user_type)
        if user_type == 1:
            return True
        else:
            return False

views.py

class Course(APIView):
    authentication_classes = [TokenAuth, ]
    permission_classes = [UserPermission,]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

这个时候如果权限认证通过,则会继续执行下一步,如果是没通过,则会返回错误信息,如下:

{"detail":"You do not have permission to perform this action."}

局部使用只需要在视图类里加入:

permission_classes = [UserPermission,][]

如果需要自定义错误信息,只需要在视图类里定义一个message属性即可,如下:

message="只有超级用户才能访问"

全局认证

REST_FRAMEWORK = {
    # 认证组件
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.TokenAuth",],
    # 权限组件
    "DEFAULT_PERMISSION_CLASSES": ["app01.permission.VipPermission",],
}

频率认证

为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次(节流,访问控制)

局部认证

组件

class MyThrottle(SimpleRateThrottle):
            scope='aaa'
            def get_cache_key(self, request, view):
                return self.get_ident(request)
                # 返回什么就以什么来作为次数限制对象

视图

class CourseView(ModelViewSet):
    authentication_classes = [self_authentication.UserAuthentication]
    permission_classes = [self_permissions.AdminPermission]
    throttle_classes = [self_throttle.LookUpCourseRateThrottle]
    queryset = models.Course.objects.all()
    serializer_class = self_serializers.CourseSerializers
    # 自定义提示信息
    def throttled(self, request, wait):
        from rest_framework import exceptions

        class MyThrottled(exceptions.Throttled):
            default_detail = '下次访问'
            extra_detail_singular = '还剩 {wait} 秒.'
            extra_detail_plural = '还剩 {wait} 秒'

        raise MyThrottled(wait)

 然后在需要进行限制的视图类中加入如下配置:

throttle_classes = [VisitRateThrottle]

在setting中:

REST_FRAMEWORK = {
                'DEFAULT_THROTTLE_RATES':{
                    'aaa':'10/m'
                }
            }

全局使用

-在setting中写

'DEFAULT_THROTTLE_CLASSES':['app01.self_throttle.LookUpCourseRateThrottle',],

如果在某视图中不需要使用只需要在视图中写

    throttle_classes = [] # 将自身的认证类置空

错误信息改成中文显示(如上文视图中所示)

def throttled(self, request, wait):
                class MyThrottled(exceptions.Throttled):
                    default_detail = '傻逼'
                    extra_detail_singular = '还剩 {wait} 秒.'
                    extra_detail_plural = '还剩 {wait} 秒'

                raise MyThrottled(wait)

猜你喜欢

转载自www.cnblogs.com/9527mwz/p/11200588.html
今日推荐