1. 程式人生 > >restfulframework--權限源碼流程

restfulframework--權限源碼流程

ensure false .get headers ota patch ros exceptio aec

定義:

判斷用戶是否擁有權限,有則放行,與django的中間件沒有沖突,

只是對某個或某類用戶定制專有的權限,可在中間件的基礎上再加上某些判定.

源碼流程:

1,所有函數進來首先走def dispatch函數.

技術分享圖片
def dispatch(self, request, *args, **kwargs):
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)  #封裝request,返回Request
        self.request = request
        self.headers 
= self.default_response_headers ##返回頭部 try: self.initial(request, *args, **kwargs) # 在這裏調用版本控制,權限控制,用戶控制,還有用戶限流 # Get the appropriate handler method if 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
def dispatch
2,調用initial函數.
技術分享圖片
def initial(request, *args, **kwargs)
    self.format_kwarg = self.get_format_suffix(**kwargs)
        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
        self.perform_authentication(request) #用戶認證
        self.check_permissions(request)     #權限驗證
        self.check_throttles(request)       #訪問頻率控制
def initial
3,執行self.check_permissions(request)
技術分享圖片
def check_permissions(self, request):
        for permission in self.get_permissions():  #實例化對象列表
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, message, None)
                )
def check_permissions()
4,實例化對象列表self.get_permissions()
技術分享圖片
def get_permissions(self):
        return [permission() for permission in self.permission_classes]
def get_permissions(self):
5,從self.permission_classes拿值
class APIView(View):
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
6,執行api_settings
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

7,實例化APISettings,並且因為api_settings.DEFAULT_PERMISSION_CLASSES,
所以調用APISettings的__getattr__方法.
技術分享圖片
class APISettings(object):
        def __getattr__(self, attr):
        if attr not in self.defaults:
            raise AttributeError("Invalid API setting: ‘%s‘" % attr)
        try:
            val = self.user_settings[attr]  #user_settings在這裏是None
        except KeyError:
            val = self.defaults[attr]   #user_settings沒有值所以調用這裏.
        if attr in self.import_strings:
            val = perform_import(val, attr)
        # Cache the result
        self._cached_attrs.add(attr)   #加到集合裏,去重
        setattr(self, attr, val)       #設置
        return val                     #
class APISettings(object):
獲取配置文件的所有信息,並返回給對象列表,等待遍歷.

8,遍歷對象列表並且判斷是否返回False,如果是True則沒有後續.
如果返回False則運行裏面內容
技術分享圖片
if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, message, None)
                )
if not permission.has_permission
9,如果沒有這個權限就執行裏面的permission_denied,也就是報錯的信息
技術分享圖片
self.permission_denied(
                    request, message=getattr(permission, message, None)
                )
self.permission_denied
10,這裏區別報錯的信息,這裏的錯誤信息可以通過前面傳message重寫信息
技術分享圖片
def permission_denied(self, request, message=None):
        #如果request.user有值
        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated()  #
        raise exceptions.PermissionDenied(detail=message)
def permission_denied(self, request, message=None):

 

restfulframework--權限源碼流程