Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-rest-framework authentication: require key parameter in URL?

I am working in Django 1.8 with the excellent django-rest-framework. I have a public RESTful API.

I would now like to start requiring a key GET parameter with this API, and disallowing any requests that do not have this parameter. I will allocate keys to users manually on request.

I have read through the DRF Authentication documentation, but I'm not sure there's anything that meets my use case. I find this strange, since my use case must be very common.

Token-based authentication requires the user to set an HTTP header. My typical API user is not sophisticated (Excel users who will be downloading CSVs), so I don't think I can ask them to do this.

I think Basic-Auth is what I need, but I'd much rather provide a simple URL-based key than a Django username and password (my app has no concept of users right now).

What is the best way to implement this?

like image 246
Richard Avatar asked Jul 29 '26 07:07

Richard


1 Answers

Create a table which will contain all the keys that you issue to someone.

Example:

class RestApiKey(models.Model):
    api_key = models.CharField(max_length=100)

Next create a custom Permision class which will check for the api Key in the url before forwarding the request to the view like:

from rest_framework import permissions
from yourappname.models import RestApiKey

class OnlyAPIPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        try:
            api_key = request.QUERY_PARAMS.get('apikey', False)
            RestApiKey.objects.get(api_key=api_key)
            return True
        except:
            return False

So the request url has to be like http://yourdomain.com/?apikey=sgvwregwrgwg

Next in your views add the permission class:

class YourViewSet(generics.ListAPIView):
    permission_classes = (OnlyAPIPermission,)

or if you are using function based views then do like:

@permission_classes((OnlyAPIPermission, ))
def example_view(request, format=None):
    . . .
like image 111
Anush Devendra Avatar answered Jul 30 '26 23:07

Anush Devendra