Issue #91 new

Support for API keys

Sym Roe
created an issue

Am I correct in thinking there isn't currently an easy way of adding API keys (something like an MD5 hash, passed before a view will return anything, like google's maps API)?

I've added it myself, by creating a model that deals with the key creation, and then manually validating the key (taken from request.GET) and returning rc.FORBIDDEN if it isn't valid.

This approach works, however it adds some boilerplate code to every view that need not be there.

Maybe a decorator along the lines of @key_required would help this? With a generic key lookup to a custom keys table would be a good solution to this?

I'd be happy to write up a patch for this, but I want to make sure there isn't an easier way before I did.

Thanks

Comments (8)

  1. Felipe Prenholato

    Isn't better write a custom authentication to handle with API keys and users? If I write something like that I use django.contrib.auth.models.User + some table linking user -> key and authenticate together this fields like Django does with password to login user.

    Just my 2 cents :), IMO is really good idea to have something like that working on piston ;)

  2. Anonymous

    Check out this simple auth object, it depends on an ApiKey model with a user (fk->auth.User), api(charfield) and status(boolfield):

    from api.models import ApiKey
    
    from django.http import HttpResponse
    
    class SimpleKeyAuthentication(object):
        
        def is_authenticated(self, request):
            if request.user.is_authenticated():
                return True
            
            key = request.GET.get('key', None)
            
            if not key:
                return False
            
            try:
                api_key = ApiKey.objects.select_related().get(key=key) 
                
                if not api_key.status: 
                    return False
                
                request.user = api_key.user
                return True
            except ApiKey.DoesNotExist, e:
                return False
            
            return not request.user in (False, None, AnonymousUser())
        
        def challenge(self):
            resp = HttpResponse("Login or API Key Required")
            resp.status_code = 401
            return resp
    
  3. Log in to comment