使用库:Django REST Framework API键时,API键无法访问Django中的视图

2024-06-16 14:14:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为我的Django项目使用DjangoRestFrameworkAPIKey

我有一个视图来创建客户端(ClientCreateAPIView),它只有在发送API密钥时才可访问。我首先创建一个组织,然后创建一个API密钥。然后,我尝试向客户端CreateApiView发出POST请求

我正在使用邮递员发送邮件请求。因此,在《邮递员》的“标题”部分,我将X-Api-Key写在Key字段和Api Key in Value字段中。但是,每当我发出POST请求时,我都会收到“未提供身份验证凭据”403错误。当我从视图中注释出权限类代码时,不会发生此错误-我可以访问该视图

我尝试了很多不同的X-Api-Key,将它们大写,删除破折号,但似乎没有任何效果。另外,我知道API密钥存在,因为在Django shell中,我可以打印出我正在使用的API密钥的id。我无法调试导致错误的原因

以下是一些可能有用的代码片段:

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/url.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'),
]

Tags: djangokeynamefromimportrestapimodels