current position:Home>Django permission management

Django permission management

2022-01-31 06:11:04 Waiting for

This is my participation 11 The fourth of the yuegengwen challenge 6 God , Check out the activity details :2021 One last more challenge

One 、 Basic use

Here we continue to use the previous example , Add corresponding permissions , Here is an example of how to use , Then analyze the permission source code

  1. stay django Create a new directory under the project utils, And establish permissions.py, Add permission control :

class MyPremission(object):
    message = " You are not a member and do not have access to "
    def has_permission(self,request,view):
        if request.user.user_type == 1: ## user_type  by 1 On behalf of ordinary users , Can't view return False
        return True
 Copy code 
  1. Use... In order view

class OrderView(APIView):
    ''' Check the order '''from utils.permissions import MyPremission
    authentication_classes = [Authentication,]    # Add Certification 
    permission_classes = [MyPremission,]    # Add permissions def get(self,request,*args,**kwargs):
        #request.user#request.auth
        ret = {'code':1000,'msg':" Your order has been completed ",'data':" Bought one. mac"}
        return JsonResponse(ret,safe=True)
 Copy code 

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [

    url(r'^api/v1/auth', views.AuthView.as_view()),
    url(r'^api/v1/order', views.OrderView.as_view()),
]
 Copy code 

models.py

from django.db import models

class UserInfo(models.Model):
    user_type_choice = (
        (1," Ordinary users "),
        (2," members "),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    username = models.CharField(max_length=32,unique=True)
    password = models.CharField(max_length=64)


class UserToken(models.Model):
    user = models.OneToOneField(to=UserInfo)
    token = models.CharField(max_length=64)
 Copy code 
  1. verification : Order business also uses user_type=1 Verify with your users , Tools are used here postman Send a request to verify , give the result as follows : Prove that our authority is in effect .

Two 、 Authority source code analysis

1. Similarly, when the request reaches the view , Execute first APIView Of dispatch Method , The following source code is in Certification Already read :

dispatch()

def dispatch(self, request, *args, **kwargs):
        """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """
        self.args = args
        self.kwargs = kwargs
        # Original request Carry on the processing , Enriched some functions #Request(# request,# parsers=self.get_parsers(),# authenticators=self.get_authenticators(),# negotiator=self.get_content_negotiator(),# parser_context=parser_context# )#request( original request,[BasicAuthentications object ,])# Get native request,request._request# Get the object of the authentication class ,request.authticators#1. encapsulation request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?try:
            #2. authentication 
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler methodif request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
 Copy code 

2. perform inital Method ,initial Method execution perform_authentication Start Certification

 def initial(self, request, *args, **kwargs):
        """ Runs anything that needs to occur prior to calling the method handler. """
        self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted#
        4. Achieve Authentication         
        self.perform_authentication(request)
        #5. Authority judgment  
        self.check_permissions(request)
        #  Visit Frequency 
        self.check_throttles(request)
 Copy code 

3. When performing the perform_authentication When the method is certified , At this time, I entered the topic of this article -- jurisdiction (check_permissions Method ), Here is check_permissions Method source code :

def check_permissions(self, request):
        """ Check if the request should be permitted. Raises an appropriate exception if the request is not permitted. """for permission in self.get_permissions():   # Loop objects get_permissions Result of method , If you don't have , Then go to the parent class to find ,
            if not permission.has_permission(request, self): # Judge... In each object has_permission Method return value ( In fact, it is authority judgment ), That's why we need to define permission classes has_permission Method 
                self.permission_denied(                       
                    request, message=getattr(permission, 'message', None) # Return no permission information , That's what we defined message Common property 
                )
 Copy code 

4. From the above source code, we can see ,perform_authentication The loop in the method get_permissions result , And judge the authority one by one , So we need to analyze get_permissions Method returns the result , Here are get_permissions Method source code :

def get_permissions(self):
        """ Instantiates and returns the list of permissions that this view requires. """return [permission() for permission in self.permission_classes]  # Like permissions, use list generation to obtain each authentication class object 
 Copy code 

5.get_permissions Method to find the permission class through self.permission_class Field search , Like the authentication class, this field is also configured globally by default , If we have defined in the view class , Then use our own defined class .

class APIView(View):

    # The following policies may be set at either globally, or per-view.
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES  # Access control 
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
 Copy code 

6. Undertaking check_permissions Method , When... In the authentication class has_permission() Method returns false when ( That is, the certification fails ), execute self.permission_denied(), Here are self.permission_denied() Source code :

def permission_denied(self, request, message=None):
        """ If request is not permitted, determine what kind of exception to raise. """if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated()
        raise exceptions.PermissionDenied(detail=message) #  If you define message attribute , Then throw the attribute value 
 Copy code 

7. Certification failure , So far django rest framework That's the end of the permission source code , Compared with the authentication source code, it is simpler .

3、 ... and 、 Built in permission verification class

django rest framework Provides a built-in permission verification class , Its essence is to define has_permission() Method to verify permissions :

# route :rest_framework.permissions
## Basic permission verification class BasePermission(object)

## Allow all class AllowAny(BasePermission)

## be based on django Authentication rights of , The official sample class IsAuthenticated(BasePermission):

## be based on django admin Access control class IsAdminUser(BasePermission)

## Is based on django adminclass IsAuthenticatedOrReadOnly(BasePermission)
.....
 Copy code 

Four 、 summary

1. Usage method :

  • Inherit BasePermission class ( recommend )
  • rewrite has_permission Method
  • has_permission Method returns True Indicates access to ,False No access

2. To configure :

### Global use 
REST_FRAMEWORK = {
   # jurisdiction "DEFAULT_PERMISSION_CLASSES":['API.utils.permission.MyPremission'],
}

## Single view use , If it is empty, it means that permission verification is not performed 
permission_classes = [MyPremission,] 


### priority 
 A single view > Global configuration 
 Copy code 

copyright notice
author[Waiting for],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/01/202201310611006880.html

Random recommended