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.

有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top