Alex Rivera | Logout

Set all pages to require login, globally?

Asked 2011-12-04T17:19:47.227
39

I want to redirect access of unauthenticated users to the login page, after which the logged-in user should be redirected to the originally requested page.

According to documentation, this is easily achieved using the @user_passes_test decorator. But it seems I'd have to decorate every view, which is crazy, there are too many and it's error-prone.

What is a good way to turn on this functionality globally (except for a small fixed set of views, such as login)? That is, default everything to logged-in-only + handle anonymous viewing explicitly, where needed.

Edit
Report

1 Answer

4

The way I solved this, was to have mixin class, with the decorator (or whatever code you need). Although you have to remember to call the super(Class, self).get(...) function, so I guess it's not so different after all.

On the other hand, having a set of mixins that does different things I found was quite good at getting a very simple view to do a lot without much code.

Edit

This is how I did in my last project:

class BaseAuthMixin(object):
    def auth_check(self, user):
        return True

    def dispatch(self, request, *args, **kwargs):
        if not self.auth_check(request.user):
            from django.http import HttpResponseRedirect
            from django.contrib.auth import logout

            is_web = False
            is_live = False

            if hasattr(self, 'get_url_name'):
                from django.core.urlresolvers import reverse
                from django.core.urlresolvers import NoReverseMatch

                try:
                    next = reverse(self.get_url_name(), kwargs=kwargs)
                except NoReverseMatch:
                    next = ''
                else:
                    next= '?next=' + next

            logout(request)

            redirect_url = settings.LOGIN_URL
            redirect_url += next

            return HttpResponseRedirect(redirect_url)
        else:
            return super(BaseAuthMixin, self).dispatch(request, *args, **kwargs)

class LoginRequiredMixin(BaseAuthMixin):
    """
    Check if the view needs the user to be logged in.
    """
    def auth_check(self, user):
        if not super(LoginRequiredMixin, self).auth_check(user):
            return False
        else:
            if hasattr(self, 'login_required'):
                if self.login_required and not user.is_authenticated():
                    return False
        return True

class MyDefaultMixin(LoginRequiredMixin):
    """
    Mixin that inherits from all common view mixins
answered 2011-12-04T17:25:07.000

Your Answer