Question

The Django project I'm currently working on is a website that should be accessed from a local network and the Internet. And part of the content should be available to anonymous users only if the visit the site from the local network (basically it's a test on the IP address), while authenticated users have access to the whole content.

I though about checking the IP as described here, but it seems to me quite bad to check the ip each time the user loads a page.

Is there a way to cleanly store user data even on anonymous user ? It would be nice to just be able to use a decorator like @login_required, but which would redirect only if the anonymous user has an external IP.

Was it helpful?

Solution

Actually, checking the ip on every requests seems to me to be one of the fastest methods available. Consider that the ip is already loaded in memory on every request, all you have to do is a simple dictionary lookup and a comparison, with a conditional string split/additional dict lookup. Compared to what happens on even the simplest page views, the performance impact is fully neglectable and comparable with the impact of using sessions or any other mechanism to save the ip.

You can write your own decorator function using user_passes_test:

from django.contrib.auth.decorators import user_passes_test
from django.utils.decorators import available_attrs
from functools import wraps

LOCAL_IPS = (
    '127.0.0.1',
    'other_ip',
    'etc.',
)

def is_local_request(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip in LOCAL_IPS

def local_ip_required(view_func):
    def wrapped_view(request, *args, **kwargs):
        if not is_local_request(request):
            raise Http404 # or PermissionDenied or redirect
        return view_func(request, *args, **kwargs)
    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)

Then simply use @local_ip_required. Note that this implementation will prevent both anonymous and logged-in users from accessing the view from an external location.

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