slogan3

Houd me bezig met het implementeren van een aangepast API-sleutelbeheersysteem in mijn Django-toepassing

description

Door het implementeren van een aangepast API-sleutelbeheersysteem, kunt u de beveiliging verbeteren, de toegang tot uw API's controleren en het gebruik effectief monitoren, zodat alleen geautoriseerde gebruikers toegang krijgen tot uw diensten.

prompt

try_prompt

Help me bij het ontwerpen en implementeren van een aangepast API-sleutelbeheersysteem in mijn Django-toepassing om toegang tot mijn API's te controleren. Beschrijf mijn huidige API-instelli ... more
generate_helper
disclaimerOnPageApi image_legal_disclaimer...

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en advies over het ontwerpen en implementeren van een aangepast API-sleutelbeheersysteem in je Django-toepassing, rekening houdend met jouw huidige OAuth2-configuratie en specifieke functies. **Huidige situatie:** - Je gebruikt OAuth2 voor authenticatie. - Je wilt aanvullende API-sleutelbeheerfunctionaliteiten toevoegen, zoals verval na 30 dagen, gebruikslimieten, en intrekkingsproces. --- ### 1. Integratie van API-sleutels naast OAuth2 Omdat OAuth2 al wordt gebruikt, kun je API-sleutels implementeren als een extra laag of alternatieve authenticatiemethode voor bepaalde API-endpoints. **Aanbevelingen:** - Voeg een model toe voor API-sleutels (`ApiKey`) dat gerelateerd is aan je gebruikers of applicaties. - Sla gegevens op zoals: - Sleutel (uniek token) - Aanmaakdatum - Vervaldatum (30 dagen na creatie) - Gebruikslimieten (bijvoorbeeld max aantal verzoeken per dag) - Status (actief, ingetrokken, verlopen) ### 2. Modeldefinitie voor API-sleutels ```python from django.db import models from django.contrib.auth.models import User import uuid from django.utils import timezone from datetime import timedelta class ApiKey(models.Model): key = models.CharField(max_length=40, unique=True, default=uuid.uuid4().hex) user = models.ForeignKey(User, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) expires_at = models.DateTimeField() is_active = models.BooleanField(default=True) request_limit = models.IntegerField(default=1000) # bijvoorbeeld requests_made = models.IntegerField(default=0) def save(self, *args, **kwargs): if not self.expires_at: self.expires_at = self.created_at + timedelta(days=30) super().save(*args, **kwargs) def is_expired(self): return timezone.now() > self.expires_at def revoke(self): self.is_active = False self.save() ``` ### 3. Functionaliteiten voor beheer - **Verval na 30 dagen:** Bij creatie wordt `expires_at` ingesteld op 30 dagen na aanmaak. - **Gebruikslimieten:** Bij elke API-aanvraag wordt gecontroleerd of het verzoek het limiet overschrijdt. - **Intrekkingsproces:** Een admin kan sleutels handmatig intrekken (`revoke()`). ### 4. Middleware of decorator voor verificatie Maak een middleware of decorator die controleert: - Of de API-sleutel geldig en actief is. - Of deze niet is verlopen. - Of het gebruikslimiet niet is overschreden. Voorbeeld van verificatie: ```python def check_api_key(request): api_key = request.headers.get('X-API-KEY') if not api_key: return False try: key_obj = ApiKey.objects.get(key=api_key, is_active=True) except ApiKey.DoesNotExist: return False if key_obj.is_expired() or not key_obj.is_active: return False if key_obj.requests_made >= key_obj.request_limit: return False # Verhoog verzoekaantal key_obj.requests_made += 1 key_obj.save() return True ``` ### 5. Automatisering en beheer - Plan een periodieke taak (bijv. via Celery of Django-cron) om verlopen sleutels te archiveren of te deactiveren. - Creëer admin-interfaces voor het genereren, intrekken en bekijken van API-sleutels. --- ### Samenvattend: - Voeg een `ApiKey`-model toe met vervaldatum en gebruikslimieten. - Stel automatische verval in op 30 dagen. - Controleer sleutels bij elke API-aanvraag. - Bied beheermogelijkheden voor het intrekken en monitoren van sleutels. Wil je dat ik je help met de volledige code-implementatie of integratie in je bestaande project?
provider: deepseek
model: deepseek-chat
Hier is een gedetailleerd plan voor het implementeren van een aangepast API-sleutelbeheersysteem in je Django-applicatie naast je bestaande OAuth2-authenticatie: ## 1. Datamodel Ontwerp ```python # models.py from django.db import models from django.contrib.auth.models import User from django.utils import timezone import secrets import hashlib class APIKey(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=100, help_text="Beschrijvende naam voor deze sleutel") # Sleutel opslag (hash voor veiligheid) key_hash = models.CharField(max_length=64, unique=True) prefix = models.CharField(max_length=8, unique=True) # Vervalinstellingen created_at = models.DateTimeField(auto_now_add=True) expires_at = models.DateTimeField() is_active = models.BooleanField(default=True) # Gebruikslimieten rate_limit = models.IntegerField(default=1000, help_text="Aanvragen per dag") requests_today = models.IntegerField(default=0) last_reset = models.DateField(auto_now_add=True) class Meta: db_table = 'api_keys' class APIKeyUsage(models.Model): api_key = models.ForeignKey(APIKey, on_delete=models.CASCADE) timestamp = models.DateTimeField(auto_now_add=True) endpoint = models.CharField(max_length=200) ip_address = models.GenericIPAddressField() class Meta: db_table = 'api_key_usage' ``` ## 2. Sleutel Generator en Beheer ```python # utils/apikey_utils.py import secrets import hashlib from datetime import timedelta from django.utils import timezone class APIKeyManager: @staticmethod def generate_key(): """Genereer een nieuwe API-sleutel""" raw_key = secrets.token_urlsafe(32) prefix = raw_key[:8] key_hash = hashlib.sha256(raw_key.encode()).hexdigest() return { 'raw_key': raw_key, 'prefix': prefix, 'key_hash': key_hash } @staticmethod def create_api_key(user, name, rate_limit=1000): """Creëer een nieuwe API-sleutel voor gebruiker""" key_data = APIKeyManager.generate_key() expires_at = timezone.now() + timedelta(days=30) api_key = APIKey.objects.create( user=user, name=name, prefix=key_data['prefix'], key_hash=key_data['key_hash'], expires_at=expires_at, rate_limit=rate_limit ) return key_data['raw_key'], api_key @staticmethod def validate_key(raw_key): """Valideer een API-sleutel""" key_hash = hashlib.sha256(raw_key.encode()).hexdigest() try: api_key = APIKey.objects.get( key_hash=key_hash, is_active=True, expires_at__gt=timezone.now() ) # Reset dagelijkse telling indien nodig if api_key.last_reset < timezone.now().date(): api_key.requests_today = 0 api_key.last_reset = timezone.now().date() api_key.save() # Controleer rate limit if api_key.requests_today >= api_key.rate_limit: return None api_key.requests_today += 1 api_key.save() return api_key except APIKey.DoesNotExist: return None ``` ## 3. Authenticatie Middleware ```python # middleware/apikey_middleware.py from django.utils.deprecation import MiddlewareMixin from .utils.apikey_utils import APIKeyManager from .models import APIKeyUsage class APIKeyMiddleware(MiddlewareMixin): def process_request(self, request): # Skip voor OAuth2 routes if request.path.startswith('/o/'): return None # Zoek API-sleutel in headers api_key = request.headers.get('X-API-Key') if api_key: validated_key = APIKeyManager.validate_key(api_key) if validated_key: request.api_key = validated_key # Log gebruik APIKeyUsage.objects.create( api_key=validated_key, endpoint=request.path, ip_address=self.get_client_ip(request) ) return None else: from django.http import JsonResponse return JsonResponse( {'error': 'Ongeldige of verlopen API-sleutel'}, status=401 ) return None def get_client_ip(self, request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip ``` ## 4. Beheer Views ```python # views/apikey_views.py from django.contrib.auth.decorators import login_required from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from .models import APIKey from .utils.apikey_utils import APIKeyManager @login_required def create_api_key(request): if request.method == 'POST': name = request.POST.get('name') rate_limit = int(request.POST.get('rate_limit', 1000)) raw_key, api_key = APIKeyManager.create_api_key( request.user, name, rate_limit ) return JsonResponse({ 'success': True, 'api_key': raw_key, # Toon alleen eenmalig! 'prefix': api_key.prefix, 'expires_at': api_key.expires_at.isoformat() }) return JsonResponse({'error': 'Alleen POST toegestaan'}, status=405) @login_required def list_api_keys(request): keys = APIKey.objects.filter(user=request.user).values( 'id', 'name', 'prefix', 'created_at', 'expires_at', 'is_active', 'rate_limit' ) return JsonResponse({'api_keys': list(keys)}) @login_required def revoke_api_key(request, key_id): try: api_key = APIKey.objects.get(id=key_id, user=request.user) api_key.is_active = False api_key.save() return JsonResponse({'success': True}) except APIKey.DoesNotExist: return JsonResponse({'error': 'Sleutel niet gevonden'}, status=404) ``` ## 5. Scheduled Tasks voor Onderhoud ```python # management/commands/cleanup_expired_keys.py from django.core.management.base import BaseCommand from django.utils import timezone from api_keys.models import APIKey class Command(BaseCommand): help = 'Verwijder verlopen API-sleutels' def handle(self, *args, **options): expired_count = APIKey.objects.filter( expires_at__lt=timezone.now() ).update(is_active=False) self.stdout.write( f'{expired_count} verlopen API-sleutels gedeactiveerd' ) ``` ## 6. Configuratie ```python # settings.py MIDDLEWARE = [ # ... andere middleware 'yourapp.middleware.apikey_middleware.APIKeyMiddleware', ] # Voeg toe aan INSTALLED_APPS INSTALLED_APPS = [ # ... andere apps 'api_keys', ] # Cron job voor dagelijkse cleanup (toevoegen aan crontab) # 0 2 * * * /path/to/venv/python /path/to/manage.py cleanup_expired_keys ``` ## 7. Gebruik in je API ```python # views.py from django.http import JsonResponse def my_api_view(request): if hasattr(request, 'api_key'): # API-sleutel authenticatie user = request.api_key.user # Je bedrijfslogica hier return JsonResponse({'data': 'API-sleutel toegang'}) else: # OAuth2 authenticatie (bestaande logica) return JsonResponse({'data': 'OAuth2 toegang'}) ``` ## Belangrijke Beveiligingsoverwegingen: 1. **Sleutels hashen** voor opslag 2. **Rate limiting** per sleutel 3. **Automatische vervaldatum** (30 dagen) 4. **Gebruikslogging** voor monitoring 5. **Prefix tonen** in beheerinterface (nooit volledige sleutel) Dit systeem werkt naast je bestaande OAuth2 en biedt eenvoudige sleutelbeheer voor machine-to-machine communicatie.