How do I check that user already authenticated from tastypie?
Asked Answered
F

4

12

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?

Flowerdeluce answered 9/9, 2011 at 14:47 Comment(0)
F
10

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?

Flowerdeluce answered 9/9, 2011 at 15:43 Comment(0)
C
9

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)
Castilian answered 29/11, 2011 at 20:46 Comment(0)
E
1

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
    }
});
Earful answered 11/3, 2013 at 20:3 Comment(0)
J
0

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 ?

Jarlath answered 17/12, 2011 at 15:13 Comment(4)
I think this will only work if request is already authenticated and a session cookie has been set. If you send a request with HTTP Basic Auth header set this will fail, because there's no session and you don't call the super class is_authenticated method, which is supposed to handle this situation.Flowerdeluce
Thanks Pulegium. "I think this will only work if request is already authenticated", is it not expected to work this way to access an API programatically ? What is the best-practice as far as authentication is concerned ? Currently I have a seperate login api which authenticate the user. Only the user successfully passed the login api can use the other restful api. Not sure if this practice is ok.Jarlath
BTW, in my login api I initiate the session-cookieJarlath
My understanding of RESTful API is that there should be no state (or session) maintained whatsoever. In other words, the information you supply with a request, should be enough to process it. That means, that you'd have to send login information with every request (as HTTP Basic auth, or API key).Flowerdeluce

© 2022 - 2024 — McMap. All rights reserved.