Reputation: 1202
I'm currently working on the project that use Android for client and Django for web server. I decided to use piston-django to create REST API authentication and I've follow this instruction: What is the right way to write a django-piston client? and write my own handler (api/handlers.py) to create and return ApiKey like this:
class ApiKeyhandler(Basehandler):
model = ApiKey
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
fields = ('user', 'keys')
def create(self, request):
attrs = self.flatten_dict(request.POST)
if self.exists(**attrs):
return rc.DUPLICATE_ENTRY
else:
apikey = ApiKey(user=request.user)
apikey.save()
return apikey
and in urls.py I use HttpBasicAuthentication for this handler:
auth = HttpBasicAuthentication(realm="Authentication API")
apikey = Resource(handler=ApiKeyHandler, authentication=auth)
but when I test it with http://hurl.it
This is the response from POST method
Can anyone tell me how to write the complete code for this question or any suggestion on this problem?
Upvotes: 1
Views: 1128
Reputation: 1202
Since nobody answer this question, I figured it out myself and some help from my friend. I have to edit ApiKeyHandler to
class ApiKeyHandler(BaseHandler):
model = ApiKey
allowed_methods = ('GET', 'POST')
fileds = ('user', 'key')
def read(self, request):
# Return the API key for request.user
values_query_set = request.user.keys.values('key')
api_key = list(values_query_set)[0]['key']
return HttpResponse(api_key)
def create(self, request):
#Create a new API Key.
# Check if API key already exists
if request.user.keys.count() > 0:
values_query_set = request.user.keys.values('key')
api_key = list(values_query_set)[0]['key']
return HttpResponse(api_key)
else:
# Create API key
api_key = ApiKey(user=request.user)
api_key.save()
return HttpResponse(api_key)
According to django-piston doc methodread
is called on GET and methodcreate
is called on POST. Thus, when client want to create new API key; client need to request HTTP POST to create API key forrequest.user
if the API key is not already exists.
Finally in models.py I need to edit the ApiKey model to
class ApiKey(models.Model):
user = models.ForeignKey(User, related_name='keys', unique=True)
key = models.CharField(max_length=KEY_SIZE, null=True, blank=True)
def save(self, *args, **kwargs):
self.key = User.objects.make_random_password(length=KEY_SIZE)
while ApiKey.objects.filter(key__exact=self.key).count():
self.key = User.objects.make_random_password(length=KEY_SIZE)
super(ApiKey, self).save(*args, **kwargs)
def __unicode__(self):
return self.key
We need to call the "real" save() method
super(ApiKey, self).save(*args, **kwargs)
and APIKeyAuthenticatin is work now.
Last but not least, when authenticating user, client need to request the HTTP request with HEADER ('Authorization', api_key).api_key
must match with therequest.user
.
Upvotes: 2