• Day 77 三大认证组件


    自定义django后台自定义注册

    from api import models
    from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
    # Register your models here.
    
    
    class UserAdmin(AuthUserAdmin):
        # 添加用户创建页面可控制字段
        add_fieldsets = (
            (
                None,
                {
                    'classes': ('wide',),
                    'fields': ('username', 'password1', 'password2', 'is_staff', 'mobile'),
                }
            ),
        )
        # 用户列表展示页面字段
        list_display = ('username', 'email', 'mobile', 'is_staff')
        
    ## 注册自定义User表,用admin管理,配置UserAdmin,定制化管理页面
    admin.site.register(models.User, UserAdmin)
    

    三大认证组件

    认证组件

    自定义认证组件

    1. 如果使用session认证,drf默认提供了SessionAuthentication
    2. 如果使用drf-jwt认证框架,drf-jwt框架提供了JSONWebTokenAuthentication
    3. 如果是自定义签发与校验token,才需要将校验token的算法写在自定义的认证类中

    多方式登录/自定义签发

    # serializers.py
    from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
    import re
    class LoginModelSerializer(serializers.ModelSerializer):
        username = serializers.CharField(max_length=16, min_length=3)
        password = serializers.CharField(max_length=16, min_length=3)
        class Meta:
            model = models.User
            fields = ('username', 'password')
    
        def validate(self, attrs):
            user = self._validate_user(attrs)
            payload = jwt_payload_handler(user)  # 生成一个载荷
            token = jwt_encode_handler(payload)  # 生成一个token
            self.content = {
                'user': user,
                'token': token
            }
            return attrs
        
    	# 多方式登录
        def _validate_user(self, attrs):
            username = attrs.get('username')
            password = attrs.get('password')
    
            if re.match(r'.*@.*', username):
                user = models.User.objects.filter(email=username).first()
            elif re.match(r'^1[3-9][0-9]{9}$', username):
                user = models.User.objects.filter(mobile=username).first()
            else:
                user = models.User.objects.filter(username=username).first()
                print(user)
    
            if not user or not user.check_password(password):
                raise serializers.ValidationError({'message': '用户信息异常'})
    
            return user
    
    # views.py
    from rest_framework.views import APIView
    class LoginAPIView(APIView):
        def post(self, request, *args, **kwargs):
            serializer = serializers.LoginModelSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            return APIResponse(results={
                'username': serializer.content.get('user').username,
                'token': serializer.content.get('token')
            })
    

    局部禁用和局部启用

    在任何一个CBV的首行

    # 局部禁用
    authentication_classes = []
    # 局部启用
    from user.authentications import JSONWebTokenAuthentication
    authentication_classes = [JSONWebTokenAuthentication]
    

    全局启用

    在settings文件中设置

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
        ]
    }
    

    权限组件

    drf自带的权限类

    1. AllowAny: 游客和登录用户有全部权限
    2. IsAuthenticated: 只有登录用户有全部权限
    3. IsAdminUser: 只有后来用户有全部权限
    4. IsAuthenticatedOrReadOnly: 游客有只读权限,登录用户有全部权限

    自定义权限类

    创建一个permission.py文件

    如:只有superuser有权限,只有vip用户有权限,只有某网段IP有权限,只有某个视图及其子类有权限

    # permissions.py
    # VIP用户权限
    class VipUserPermission(BasePermission):
        def has_permission(self, request, view):
            for group in request.user.groups.all():
                if group.name.lower() == 'vip':
                    return True
            return False
    

    添加权限

    在CBV中添加

    permission_classes = [permissions.VipUserPermission]
    

    频率组件

    drf自带的频率类

    1. AnonRateThrottle: 只对游客进行频率限制
    2. UserRateThrottle: 对所有用户进行频率限制

    自定义频率组件类

    如: 对IP进行限次,对电话进行限制,对视图某些信息进行限制

    from rest_framework.throttling import SimpleRateThrottle
    """
    自定义频率类
    1) drf默认提供了一些频率类 
        AnonRateThrottle:只对游客进行频率限制
        UserRateThrottle:对所有用户进行频率限制
    2)如果有特殊需要,需要自定义频率类
        如:对ip进行限次、对电话进行限制、对视图某些信息进行限次
    """
    class MobileRateThrottle(SimpleRateThrottle):
        """
        1)设置scope字符串类属性,同时在settings中进行drf配置DEFAULT_THROTTLE_RATES
            eg: DEFAULT_THROTTLE_RATES = {'mobile': '1/min'}
        2)重写get_catch_key方法:
            返回与限制条件有关的字符串,表示限制
            返回None,表示不限制
        """
        scope = 'mobile'
        def get_cache_key(self, request, view):
            if not request.user.is_authenticated or not request.user.mobile:
                return None  # 匿名用户 或 没有电话号的用户 都不限制
    
            # 只要有电话号的用户踩进行限制
            return self.cache_format % {
                'scope': self.scope,
                'ident': request.user.mobile
            }
    

    添加频率限制

    在settings配置文件中配置

    REST_FRAMEWORK = [
        'DEFAULT_THROTTLE_RATES': {
            'user': '5/m',
            'anon': '3/m',
            'mobile': '3/m'
        }
    ]
    
  • 相关阅读:
    ssh出错 sign_and_send_pubkey: signing failed: agent refused operation
    使用dd命令制作U盘启动盘wodim刻录光盘cd dvd
    Python示例项目学习
    Python知乎上推荐的项目
    Python10大热门项目
    Python开源项目Top30
    Python适合练手的项目
    Python80个练手项目列表
    Python爬虫实例项目
    Python实例100个(基于最新Python3.7版本)
  • 原文地址:https://www.cnblogs.com/2222bai/p/12149663.html
Copyright © 2020-2023  润新知