I am working on a Django-powered website, a website with no actual login of it’s own. I am using 3rd parties (Facebook/Twitter/etc) to provide authentication for my users. The issue I ran into is, what happens if a user goes to a url that is protected with a @login_requred decorator? Well, it should be simple - Django redirects the user to the supposed login page, with a parameter of next=/some/url/to/go/to. Since my app doesn’t do the login itself, the user then clicks on which third party service they wish to authenticate against. The user is taken through the third party’s authentication workflow and redirected back to my site. The problem here is that the “next” url parameter is lost in the process. I thought I would need to write a @login_required_session decorator, which would be less than ideal if my app then uses built in views with the @login_required decorator.

There is a simple work around for this: shove the value for the “next” url paramter into the session of where ever your login page is. Upon return, check to see if a session value exists for url redirection and if so, use it. Here is the code I came up with:

    # If we have a redirect URL in our session, redirect to it.
    if request.session.has_key('redirect-url'):
        redirect_url = request.session.get('redirect-url')
        del request.session['redirect-url']
        return HttpResponseRedirect(redirect_url)

    # if the url has a next paramter, save it in the session
    if request.GET.get('next', None):
        request.session['redirect-url'] = request.GET['next']

Note here that where the user is redirected to if not logged in and where the user is redirected to post-third party authentication is the same for me. If you have two separate views for this, you’d break the above code up and put them where they make sense.