Skip to content

Instantly share code, notes, and snippets.

@iMerica
Last active September 7, 2018 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iMerica/6e08d2be799d0c4494ee29cb6fa21111 to your computer and use it in GitHub Desktop.
Save iMerica/6e08d2be799d0c4494ee29cb6fa21111 to your computer and use it in GitHub Desktop.
Custom Auth for Django/DRF that allows for multiple API Tokens per user.
from rest_framework.authentication import TokenAuthentication
from .models import RESTAPIToken
class CustomRestAPIAuthentication(TokenAuthentication):
""" Custom Authentication """
def get_model(self):
return RESTAPIToken
import binascii
import os
from django.conf import settings
from django.db import models
class RESTAPIToken(models.Model):
""" Tokens specifically for REST API Access (with M2M support ) """
key = models.CharField(_("Key"), max_length=40, primary_key=True)
label = models.CharField(max_length=30, null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name='rest_api_auth_token',
on_delete=models.CASCADE,
)
created = models.DateTimeField(_("Created"), auto_now_add=True)
objects = models.Manager()
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(RESTAPIToken, self).save(*args, **kwargs)
@staticmethod
def generate_key():
return binascii.hexlify(os.urandom(20)).decode()
def __str__(self):
return self.key
from rest_framework import serializers
from .models import RESTAPIToken
class RestAPITokenSerializer(serializers.ModelSerializer):
class Meta:
model = RESTAPIToken
fields = ['key', 'label', 'created']
from .views import RestAPITokenView, CoolPublicAPIResource
from django.conf.urls import url
PRIVATE_API_PREFIX = '/private/api/'
PUBLIC_API_PREFIX = '/public/api/'
urlpatterns = [
url(fr'^{PRIVATE_API_PREFIX}api-tokens/$', RestAPITokenView.as_view(), name='api_tokens'),
url(fr'^{PUBLIC_API_PREFIX}/cool-public-api-resource/$', CoolPublicAPIResource.as_view(), name='cool_resource'),
]
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin, ListModelMixin, CreateModelMixin
from .serializers import RestAPITokenSerializer
from .authentication import CustomRestAPIAuthentication
class RestAPITokenView(GenericAPIView, ListModelMixin, CreateModelMixin):
""" For listing, creating REST API tokens in your regular UI """
authentication_classes = (TokenAuthentication,) # Use the normal auth class
serializer_class = RestAPITokenSerializer
def get_queryset(self):
return RESTAPIToken.objects.filter(user=self.request.user)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
class CoolPublicAPIResource(GenericAPIView, ListModelMixin):
authentication_classes = (CustomRestAPIAuthentication,)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment