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'
    }
]
原文地址:https://www.cnblogs.com/2222bai/p/12149663.html