Question

When user authenticates in Django, how do I check that from tastypie?

Once user logs on, the view includes some JS that pulls data from API, which is backed by tastypie.

I have basic authentication/djangoauthorisation set up on my resources, so the browser pops up http auth window. Is there any way to avoid this?

My idea so far is to extend BasicAuthentication so that it first checks session data and when it doesn't find it, it falls back to http auth? AFAIK AJAX calls include session cookies, so this in theory should work? Has anybody done something similar?

Was it helpful?

Solution

I have this solution so far:

class MyBasicAuthentication(BasicAuthentication):
    def __init__(self, *args, **kwargs):
        super(MyBasicAuthentication, self).__init__(*args, **kwargs)

    def is_authenticated(self, request, **kwargs):
        from django.contrib.sessions.models import Session
        if 'sessionid' in request.COOKIES:
            s = Session.objects.get(pk=request.COOKIES['sessionid'])
            if '_auth_user_id' in s.get_decoded():
                u = User.objects.get(id=s.get_decoded()['_auth_user_id'])
                request.user = u
                return True
        return super(MyBasicAuthentication, self).is_authenticated(request, **kwargs)

which seems to do what I want. If user is logged on, then session contains _auth_user_id, if not, the key is missing.

Anyone can think of any problems this approach may cause?

OTHER TIPS

You may want to check out this ticket on tastypie's GitHub:

https://github.com/toastdriven/django-tastypie/issues/197

The author suggests a very clean approach to authenticate the call with both the session and the API key methods.

There goes the snippet:

class ApiKeyPlusWebAuthentication(ApiKeyAuthentication):
def is_authenticated(self, request, **kwargs):
    if request.user.is_authenticated():
        return True

    return super(ApiKeyPlusWebAuthentication, self).is_authenticated(request, **kwargs)

def get_identifier(self, request):
    if request.user.is_authenticated():
        return request.user.username
    else:
        return super(ApiKeyPlusWebAuthentication, self).get_identifier(request)

Once the user is logged in through your API, you have a Django user session. If you want to check if the user is still logged in (on page refresh for example). You can do:

from tastypie.resources import Resource

class LoggedInResource(Resource):
    class Meta:
        pass

    def get_list(self, request, **kwargs):

        from django.http import HttpResponse

        if request.user.is_authenticated():
            return HttpResponse(status=200)
        else:
            return HttpResponse(status=401)

Client check:

$.ajax({
    type: "GET",
    url: '/api/loggedin/',
    success: function(data) {
        // logged in
    },
    error: function() {
        // not logged in
    }
});

Pulegium

Why not just as simple as the following:

class CommAuthentication(BasicAuthentication):
    def __init__(self, *args, **kwargs):
        super(CommAuthentication, self).__init__(*args, **kwargs)

    def is_authenticated(self, request, **kwargs):
        return request.user.is_authenticated()

I just start to learn tastypie. the above code seemed works for me. Any advantage of your solution ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top