Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

login_required decorator on ajax views to return 401 instead of 302

Tags:

ajax

django

While writing some views to respond to ajax requests i find it somewhat strange that the login_required decorator always returns a 302 status code for not authenticated users. As these views are ajax views, this seems somewhat inappropriate. I do not want the user to log in in such a case, but i want Django to tell the client that authentication is required to access such a view (a 401 should be the right status code, i think).

To achieve this, i started to write my own decorator login_required_ajax, but somehow this is beyond my skills. This is what i have come up with so far:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)

        if function is None:
            return _decorator
        else:
            return _decorator(function)

When using this decorator on a view, i get a ViewDoesNotExist exception as soon as i try to access any page on the site.

I first thought that the problem could be the direct return of an HttpResponse when a user is not authenticated, because a response object is not a callable. But then the decorator should work as long as i do not try to access the view in question, shouldn't it? And if this really is the crux, how can i write a decorator that returns a HttpResponse with a status code of 401?

like image 939
marue Avatar asked Apr 05 '12 14:04

marue


1 Answers

That's a pretty good attempt. Here's a couple of problems I spotted:

  1. Your _decorator function should return _wrapped_view.
  2. The indentation for your if function is None block is a bit off -- the login_required_ajax function needs to return the decorated function.

Here's the decorator with those changes made:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)
        return _wrapped_view

    if function is None:
        return _decorator
    else:
        return _decorator(function)
like image 149
Alasdair Avatar answered Oct 27 '22 00:10

Alasdair



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!