Skip to content

djangorestframework-api-key

Introduction

Django REST Framework API Key is a powerful library for allowing server-side clients to safely use your API. These clients are typically third-party backends and services (i.e. machines) which do not have a user account but still need to interact with your API in a secure way.

Quickstart

Install with pip:

pip install "djangorestframework-api-key==2.*"
Important

It is highly recommended to pin your dependency to the latest major version (as depicted above), as breaking changes may and will happen between major releases.

Add the app to your INSTALLED_APPS:

# settings.py

INSTALLED_APPS = [
  # ...
  "rest_framework",
  "rest_framework_api_key",
]

Run the included migrations:

python manage.py migrate

To learn how to configure permissions and manage API keys, head to the User Guide.

Setting permissions

The HasAPIKey permission class protects a view behind API key authorization.

You can set the permission globally:

# settings.py
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework_api_key.permissions.HasAPIKey",
    ]
}

or on a per-view basis:

# views.py
from rest_framework.views import APIView
from rest_framework_api_key.permissions import HasAPIKey

class UserListView(APIView):
    permission_classes = [HasAPIKey]
    # ...

See also Setting the permission policy for more information on using permission classes in the Django REST Framework.

Tip

You can use the bitwise operators | and & to compose HasAPIKey with other permission classes and achieve more complex authorization behaviour.

For example, to require a valid API key or authentication credentials, use:

from rest_framework.permissions import IsAuthenticated
from rest_framework_api_key.permissions import HasAPIKey
# ...
permission_classes = [HasAPIKey | IsAuthenticated]

Making authorized requests

Authorization header

By default, clients must pass their API key via the Authorization header. It must be formatted as follows:

Authorization: Api-Key <API_KEY>

where <API_KEY> refers to the full generated API key (see Creating and managing API keys below).

To know under which conditions access is granted, please see Grant scheme.

If wanting to also customize the keyword used for parsing the Api-Key, please see API key Custom Keyword

Custom header

You can set the API_KEY_CUSTOM_HEADER setting to a non-None value to require clients to pass their API key in a custom header instead of the Authorization header.

This is useful if you plan to use API keys AND an authentication scheme which already uses the Authorization header (e.g. token-based authentication).

For example, if you set:

# settings.py
API_KEY_CUSTOM_HEADER = "HTTP_X_API_KEY"

then clients must make authorized requests using:

X-Api-Key: <API_KEY>

where <API_KEY> refers to the full generated API key.

Please refer to HttpRequest.META for more information on headers in Django.


Creating and managing API keys

Admin site

When it is installed, djangorestframework-api-key adds an "API Key Permissions" section to the Django admin site where you can create, view and revoke API keys.

Note

Upon creating an API key from the admin, the full API key is shown only once in a success message banner. This is what should be passed in authorization headers. After creation, only the prefix of the API key is shown in the admin site, mostly for identification purposes. If you lose the full API key, you'll need to regenerate a new one.

Programmatic usage

API keys can be created, viewed and revoked programmatically by manipulating the APIKey model.

Note

The examples below use the Django shell.

  • You can view and query APIKey like any other model. For example, to know the total number of API keys:
>>> from rest_framework_api_key.models import APIKey
>>> APIKey.objects.count()
42
  • If you wish to create an API key programmatically, you'll most likely want a one-time access to its generated key too. To do so, use the .create_key() method on the APIKey objects manager instead of .create():
>>> from rest_framework_api_key.models import APIKey
>>> api_key, key = APIKey.objects.create_key(name="my-remote-service")
>>> # Proceed with `api_key` and `key`...
Danger

To prevent leaking API keys, you must only give the key to the client that triggered its generation. In particular, do not keep any trace of it on the server.

  • To retrieve an APIKey instance based on its generated key (which is not stored in the database) use the .get_from_key() method on the APIKey objects manager instead of .get(). This is useful if you'd like to access an APIKey object from a view protected by a HasAPIKey permission.
from rest_framework.views import APIView
from rest_framework_api_key.models import APIKey
from rest_framework_api_key.permissions import HasAPIKey

from .models import Project

class ProjectListView(APIView):
    permission_classes = [HasAPIKey]

    def get(self, request):
        """Retrieve a project based on the request API key."""
        key = request.META["HTTP_AUTHORIZATION"].split()[1]
        api_key = APIKey.objects.get_from_key(key)
        project = Project.objects.get(api_key=api_key)

Test Your API

Normal Authorization

To test the API key authentication:

  • Include the API key in the Authorization header of your request:
Authorization: Api-Key <your-api-key>
  • Make sure to handle invalid or missing API keys appropriately.

APIs

Using API_KEY_CUSTOM_HEADER

# settings.py
API_KEY_CUSTOM_HEADER = "HTTP_X_API_KEY"

APIs restfox