码迷,mamicode.com
首页 > 其他好文 > 详细

DRF(五)

时间:2019-09-08 00:46:25      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:orm   import   没有权限   min   cep   generics   实例化   register   *args   

一.权限机制

        基于权限的认证
        基于角色的认证:
                  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(可以登录后台管理系统的用户)

 

 

 

DRF(五)

标签:orm   import   没有权限   min   cep   generics   实例化   register   *args   

原文地址:https://www.cnblogs.com/sima-3/p/11483921.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!