DRF Simple API Key

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_active

You 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.

On this page