Authentication in DRF
Authentication Process Flow
class APIView(View):
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
def get_permissions(self):
return [permission() for permission in self.permission_classes]
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)
)
Built-in Permission Classes
class IsAuthenticated(BasePermission):
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
class IsReadOnly(BasePermission):
def has_permission(self, request, view):
return request.method in SAFE_METHODS
Custom Permission Implemenattion
class AdminOnlyPermission(BasePermission):
def has_permission(self, request, view):
return request.user.is_staff
class UserViewSet(ModelViewSet):
permission_classes = [AdminOnlyPermission]
queryset = User.objects.all()
serializer_class = UserSerializer
Rate Limiting in DRF
Rate Limiting Process Flow
class APIView(View):
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
def get_throttles(self):
return [throttle() for throttle in self.throttle_classes]
def check_throttles(self, request):
for throttle in self.get_throttles():
if not throttle.allow_request(request, self):
self.throttled(request, throttle.wait())
Built-in Throttle Classes
class SimpleRateThrottle(BaseThrottle):
def parse_rate(self, rate):
if not rate:
return (None, None)
count, period = rate.split('/')
return (int(count), {'s':1,'m':60,'h':3600}[period[0]])
class UserRateThrottle(SimpleRateThrottle):
scope = 'user'
def get_cache_key(self, request, view):
if request.user.is_authenticated:
return f"throttle_user_{request.user.pk}"
Custom Throttle Implementatino
class IPRateThrottle(SimpleRateThrottle):
scope = 'ip'
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR')
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'ip': '100/day',
'user': '1000/hour'
}
}