zoukankan      html  css  js  c++  java
  • DRF(五)

    一.权限机制

            基于权限的认证
            基于角色的认证:
                      RBAC(Role-Based Access Control)

                      Django采用六表:

    二.自定义User表

    models.py:

    from
    django.db import models class Car(models.Model): name = models.CharField(max_length=64) is_delete = models.BooleanField(default=0) class Meta: db_table = 'old_boy_car' verbose_name = '汽车' verbose_name_plural = verbose_name def __str__(self): return self.name from django.contrib.auth.models import AbstractUser class User(AbstractUser): mobile = models.CharField(max_length=11) class Meta: db_table = 'old_boy_user' verbose_name = '用户' verbose_name_plural = verbose_name def __str__(self): return self.username


    settings.py:
    # 配置自定义User表
    AUTH_USER_MODEL = 'api.user'

    后台注册:

    from django.contrib import admin
    
    from . import models
    
    admin.site.register(models.Car)
    admin.site.register(models.User)  此时user不再是系统的user,需要注册

    在测试文件中进行六表orm操作:

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dg_proj.settings")
    import django
    django.setup()
    
    """ 相互访问
    User:  groups  user_permissions
    Group:user_set permissions
    Permission:user_set  group_set
    """
    from api.models import User
    from django.contrib.auth.models import Group
    from django.contrib.auth.models import Permission
    
    user = User.objects.get(pk=2)  # type: User
    print(user.username)
    print(user.groups.first().name)
    print(user.user_permissions.first())
    
    group = Group.objects.get(pk=1)
    print(group)
    print(group.user_set.get(pk=2))
    print(group.permissions.get(pk=1))
    
    permission = Permission.objects.get(pk=19)  跟user有关
    print(permission)
    print(permission.user_set.first())
    permission = Permission.objects.get(pk=1)   跟group有关
    print(permission.group_set.first())

    三.需要认证访问的接口准备

        a.主路由

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls')),
    ]

       b.路由分发

    from django.conf.urls import url
    from . import views
    urlpatterns = [
        # 用户的详情消息,只有在登录后才能查看
        url(r'^users/(?P<pk>.*)/$', views.UserRetrieveAPIView.as_view()),
    
        # 游客只可以查看,登录后可以增删改
        url(r'^cars/$', views.CarModelViewSet.as_view({
            'get': 'list',
            'post': 'create'
        })),
        url(r'^cars/(?P<pk>.*)/$', views.CarModelViewSet.as_view({
            'get': 'retrieve',
            'put': 'update',
            'patch': 'partial_update',
            'delete': 'destroy',
        })),
    ]

     c.序列化类

    from rest_framework import serializers
    from . import models
    
    
    class UserModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.User
            fields = ('username', 'mobile')
    
    class CarModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Car
            fields = ('name',)

      d.视图类

    from rest_framework.generics import RetrieveAPIView
    from . import models, serializers
    
    class UserRetrieveAPIView(RetrieveAPIView):
    
    
        queryset = models.User.objects.filter(is_active=True)
        serializer_class = serializers.UserModelSerializer
    
    
    from rest_framework.viewsets import ReadOnlyModelViewSet
    
    
    class CarReadOnlyModelViewSet(ReadOnlyModelViewSet):
        queryset = models.Car.objects.filter(is_delete=False)
        serializer_class = serializers.CarModelSerializer

    四.认证源码分析与session认证

    1.入口:

    2.找dispach方法:

    3.找auth认证入口:

    4.进入auth认证方法,返回request(封装后)的user方法

    5.进入Request类找user

    6.开始认证:

    7.找Request实例化的认证属性,认证对象的赋值入口

    8.认证赋值:

    9.把rest_framwork的settings.py文件中有关认证的配置复制到自己的settings.py文件中:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            # django默认session校验:校验规则 游客 及 登录用户
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication',
        ]
    }

    10.session校验登录用户和游客,找authentication.py文件的SessionAuthentication类:

       def authenticate(self, request):
            """
            Returns a `User` if the request session currently has a logged in user.
            Otherwise returns `None`.
            """
    
            # Get the session-based user from the underlying HttpRequest object
            user = getattr(request._request, 'user', None)
            游客不进行csrf校验
            # Unauthenticated, CSRF validation not required
            if not user or not user.is_active:
                return None
            登录用户进行csrf校验
            self.enforce_csrf(request)
    
            # CSRF passed with authenticated user
            return (user, None)

    可自定义携带校验信息但未通过的非法用户:

    五.认证原理:

    认证校验方法:
    返回None => 游客
    返回user,auth => 登录用户
    抛出异常 => 非法用户
    
    1)如果前台没有携带认证信息,直接定义为游客
    2)如果前台携带了认证信息并认证通过,定位为登录用户,将登录的用户user对象保存在 requset.user 中
    3)如果前台携带了认证信息但没有认证通过,一般都定义为游客
        可以自定义为非法用户,抛出 认证失败 异常,但是不建议直接操作,可以交给权限组件进一步处理
        rest_framework.exceptions 的 AuthenticationFailed

    六.权限校验:

      1. 找到步骤2,3进入权限入口:

    2.进入权限赋值入口get_permissions

    3.把rest_framwork的settings.py文件中有关权限的配置复制到自己的settings.py文件中(可找permissions.py):

    # drf配置
    """
    AllowAny:允许所有用户
    IsAuthenticated:只允许登录用户
    IsAuthenticatedOrReadOnly:游客只读,登录用户无限制
    IsAdminUser:是否是后台用户
    """
    REST_FRAMEWORK = {
    
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',
            # 全局配置:一站式网站(所有操作都需要登录后才能访问)
            # 'rest_framework.permissions.IsAuthenticated',
        ],
    }

    4.视图校验

    from rest_framework.generics import RetrieveAPIView
    from . import models, serializers
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.response import Response
    #登录才能查看,游客不可查看
    class UserRetrieveAPIView(RetrieveAPIView):
        # 局部配置
        # 局部取消认证组件:authentication_classes = []
        # 局部启用认证组件:authentication_classes = [认证类们]
        # 局部取消权限组件: permission_classes = []
        # 局部启用权限组件: permission_classes = [权限类们]
        permission_classes = [IsAuthenticated]
    
        queryset = models.User.objects.filter(is_active=True)
        serializer_class = serializers.UserModelSerializer
    
    
    from rest_framework.viewsets import ModelViewSet
    # 游客只可以查看,登录后可以增删改
    from rest_framework.permissions import IsAuthenticatedOrReadOnly
    class CarModelViewSet(ModelViewSet):
        queryset = models.Car.objects.filter(is_delete=False)
        serializer_class = serializers.CarModelSerializer
        permission_classes = [IsAuthenticatedOrReadOnly]
    
        def destroy(self, request, *args, **kwargs):
            obj = self.get_object()
            obj.is_delete = True
            obj.save()
            return Response('删除成功')

    5.权限校验原理:

    权限校验方法:
    返回False => 没有权限,将信息返回给前台
    返回True => 拥有权限,进行下一步认证(频率认证)
    
    1)AllowAny:允许所有用户,校验方法直接返回True
    2)IsAuthenticated:只允许登录用户
        必须request.user和request.user.is_authenticated都通过
    3)IsAuthenticatedOrReadOnly:游客只读,登录用户无限制
        get、option、head 请求无限制
        前台请求必须校验 request.user和request.user.is_authenticated
    4)IsAdminUser:是否是后台用户
        校验 request.user和request.user.is_staff    is_staff(可以登录后台管理系统的用户)

     

  • 相关阅读:
    JVM知识体系
    RabbitMQ学习11死信队列(拒绝消息)
    JUC知识体系
    RabbitMQ学习10死信队列(队列达到最大长度)
    Dropdownlist+objectdatasource设定“请选择”默认选项
    sql DATEPART函数使用
    win7 'IIS APPPOOL\Classic .NET AppPool' 登录失败
    sqlserver2000还原数据库时报设备激活错误的解决方法
    vss和vs2008组合搭建源代码管理器
    在配置win7 IIS浏览网站时 检测到在集成的托管管道模式下不适用的ASP.NET设置 的解决方法
  • 原文地址:https://www.cnblogs.com/sima-3/p/11483921.html
Copyright © 2011-2022 走看看