Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sign-in? Django TastyPie with ApiKeyAuthentication actual authentication Process

I have an Adobe Air mobile application that communicates with Django via TastyPie. To use the app people have to register first. Therefore they have to supply their email and password. Afterwards they will be able to "login". I thought it would be the best idea that after entering a successful username/password combination, the api-key will be sent back to the mobile app where it will be cached, so the user is "logged in".

Please tell me if you think there is a better way for registering and "logging in" users.

Inside Django I have a UserRessource class that I use to register new users when sending data via POST:

class UserResource(ModelResource):
    class Meta:
        allowed_methods = ['get', 'post']
        queryset = User.objects.all()
        resource_name = 'auth'
        authentication = Authentication()
        authorization = Authorization()
        fields = ['username', 'email']

    def obj_create(self, bundle, request=None, **kwargs):
        username, email, password = bundle.data['username'], bundle.data['password'], bundle.data['password'], 
        try:
            bundle.obj = User.objects.create_user(username, email, password)
        except IntegrityError:
            raise BadRequest('That username already exists')
        return bundle

That works very well.

But now I'm struggling with the actual login process. In my opinion it would be best to send username and password via GET (and https) to this ressource and if those are valid, return the users api key. But would that be possible? And is it clean? Usually TastyPie would show all users currently in the DB if you send a GET request to that ressource. But I dont need that data, so I could overwrite that somehow. I already checked http://django-tastypie.readthedocs.org/en/v0.9.9/resources.html but I don't get it to work. Is it even possible to overwrite that behaviour?

So the actual questions are Whats the best way to "sign in" a user using ApiKeyAuthentication? And Is my approach right and clean or do you have a better method? and Do you have any examples for this case?

Thanks alot in advance!

like image 365
Matthias Scholz Avatar asked Sep 06 '12 08:09

Matthias Scholz


2 Answers

I'm using BasicAuth so it may be slightly different. But my solution is basicaly an empty resource that requires authentication. If the authentication is a success the service returns response code 200 and the authenticated user, I override obj_get_list and stuff the authenticated user in there. If the credentials are wrong the service returns response code 401.

 class LoginResource(ModelResource):
        class Meta:
            allowed_methods = ['get']
            resource_name = 'login'
            include_resource_uri = False
            object_class = User
            authentication = BasicAuthentication()
            authorization = DjangoAuthorization()

        def obj_get_list(self, bundle, **kwargs):
            return [bundle.request.user]
like image 159
Roge Avatar answered Nov 14 '22 09:11

Roge


Okay I'll try to explain my point of view on the topic:

First the UserResource example on the tastypie page for me has one significant issue: The User Objects should not be presented at any time to the single User, they should be able to see they're own "profile" or whatever but never browse and see others. Of course that can be done and with UserResource by clearing the main "list view" of that resource and applying the APIKeyAuth to the individual profiles, but still I don't like the idea of UserResource.

Second in the form when you are developing an API(such as tastypie usage) the APIKey is the actual "password" so what should be send on request is not the username and password but the username and APIKey, which is obtained in other manners(normally an e-mail or some kind of website based UI). Than they are recommended to be send via Authorization Header and not in GET parameters.

Third when we are talking about API there is no such thing as sign-in - at least not in the RESTFULL APIs - it is in some sense connectionless, so you actually going to send the Authorization header with each request. As to the question yes you can overwrite the data. Look at the hydrate/dehydrate cycle in the Tastypie docs to understand how does it renders the content and if you have more question go ahead and ask.

like image 31
Alex Botev Avatar answered Nov 14 '22 10:11

Alex Botev