Permissions
Using permission classes for API key authorization
Permissions or authorization in Django are used to make sure the entity making the request has the right to read/write the resource. By default, entity classes are set to django.contrib.auth.User. We also provide a permission class, which by default ensures that only active entities users have permission to read/write the resource.
class IsActiveEntity(BasePermission):
"""
A base permission that only checks if the entity (by default, the Django user) is
active or not.
"""
message = "Entity is not active."
def has_permission(self, request: HttpRequest, view: typing.Any) -> bool:
return request.user.is_active
def has_object_permission(
self, request: HttpRequest, view: typing.Any, obj
) -> bool:
return request.user.is_activeYou can then call use this class in your view 👇
from drf_simple_apikey.permissions import IsActiveEntity
class YourViewSet(viewsets.ViewSet):
...
authentication_classes = (APIKeyAuthentication, )
permission_classes = (IsActiveEntity, )Feel free to read the code of the permission class at https://github.com/koladev32/drf-simple-apikey/blob/main/drf_simple_apikey/permissions.py.
Scopes
An APIKey can be restricted to a set of scopes using the scopes field on the model. A key created without any scope is unrestricted and can be used for any action. Scopes are just strings, so you're free to design your own scheme ("read"/"write", "fruits:read", "orders:refund", ...).
api_key, key = APIKey.objects.create_api_key(
entity=user,
scopes=["fruits:read"],
)To enforce scopes on a view, declare a required_scopes attribute on it and add the HasAPIKeyScopes permission class:
from rest_framework import viewsets
from drf_simple_apikey.backends import APIKeyAuthentication
from drf_simple_apikey.permissions import HasAPIKeyScopes
class FruitViewSets(viewsets.ViewSet):
authentication_classes = (APIKeyAuthentication,)
permission_classes = (HasAPIKeyScopes,)
required_scopes = ["fruits:read"]A request authenticated with a key that doesn't carry every scope listed in required_scopes gets a 403 Forbidden response. Keys created without a scopes value (None or an empty list) always satisfy this check, so the feature is fully opt-in and backward compatible with existing keys.