1

I am using the DjangoRestFrameworkAPIKey for my Django Project

I have a view to create a client(ClientCreateAPIView), which is only accessible when an API Key is sent. I first create an Organization and then I create an API Key. Then, I try to make a POST request to the ClientCreateAPIView.

I am using POSTMAN to send POST requests. So in Postman, in the "Header" section, I have X-Api-Key written in the Key Field and the API Key in in Value Field. However, whenever I make a POST request, I get a "Authentication credentials were not provided." 403 error. This error does not happen, when I comment out the permission classes code from the view - I can access the view then.

I tried a lot of variations of X-Api-Key, capitalizing them, removing the dashes but nothing seems to work. Also, I know that the API Key exists because in the Django shell, I can print out the id of the APIKey that I am using. I cannot debug what is causing the error.

Following are some code snippets that could be useful:

mysite/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api',
    'rest_framework',
    'rest_framework_api_key',
]

API_KEY_CUSTOM_HEADER = "HTTP_X_API_KEY"

api/models.py

from django.db import models
from rest_framework_api_key.models import AbstractAPIKey

class Organization(models.Model):
    name = models.CharField(max_length=128)

class Client(models.Model):
    name = models.CharField(max_length=128)


class OrganizationAPIKey(AbstractAPIKey):
    organization = models.ForeignKey(
        Organization,
        on_delete=models.CASCADE,
        related_name="api_keys",
    )

api/serializers.py

from rest_framework import serializers
from api.models import Organization, OrganizationAPIKey, Client

class OrganizationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Organization
        fields = ['name',]

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = ['name',]

class OrganizationAPIKeySerializer(serializers.ModelSerializer):

    class Meta:
        model = OrganizationAPIKey
        fields = ('id', 'prefix', 'hashed_key', 'created', 'name', 'revoked', 'expiry_date')

api/views.py

from django.shortcuts import render
from rest_framework import generics
from api.models import Organization, OrganizationAPIKey, Client
from rest_framework import status
from api.serializers import OrganizationSerializer, OrganizationAPIKeySerializer, ClientSerializer
from rest_framework.response import Response
from rest_framework_api_key.permissions import HasAPIKey

class OrganizationCreateAPIView(generics.CreateAPIView):
    """View to create Organziation"""
    serializer_class = OrganizationSerializer

class OrganizationAPIKeyCreateAPIView(generics.CreateAPIView):
    """ View to create API Keys """
    queryset = OrganizationAPIKey.objects.all()
    serializer_class = OrganizationAPIKeySerializer

    def create(self, request):
        orgz = Organization.objects.get(name=request.data['organization'])
        api_key, key = OrganizationAPIKey.objects.create_key(organization=orgz, name=request.data['name'])
        return Response({'name':str(api_key), 'key': str(key)}, status=status.HTTP_201_CREATED)

class ClientCreateAPIView(generics.CreateAPIView):
    """View to create Client"""
    permission_classes = [HasAPIKey]
    serializer_class = ClientSerializer

mysite/urls.py

from django.contrib import admin
from django.urls import path
from api.views import OrganizationAPIKeyCreateAPIView, OrganizationCreateAPIView, ClientCreateAPIView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/organization/', OrganizationCreateAPIView.as_view(), name='organization'),
    path('api/key/', OrganizationAPIKeyCreateAPIView.as_view(), name='key'),
    path('api/client/', ClientCreateAPIView.as_view(), name='client'),
]
4
  • So you facing Authentication credentials were not provided." 403 error and you want to get rid off this right ? Commented May 19, 2020 at 14:58
  • Yes, that is correct. Commented May 19, 2020 at 15:28
  • are you using Python 3.6+, Django 2.0+ and Django REST Framework 3.8+ ? Commented May 19, 2020 at 16:12
  • If you're testing this with manage.py runserver the custom header will be stripped (default behaviour if the header contains underscores) If you're using Apache with mod_wsgi, please check this answer Commented Jan 13, 2021 at 23:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.