Django的不同类型的匿名用户

时间:2013-08-13 09:23:46

标签: django django-authentication anonymous-users

我目前正在开发的Django项目是一个应该从本地网络和互联网访问的网站。只有当从本地网络访问网站时,部分内容才能供匿名用户使用(基本上是对IP地址的测试),而经过身份验证的用户可以访问整个内容。

我虽然关于检查IP as described here,但每次用户加载页面时检查ip都是非常糟糕的。

有没有办法在匿名用户上干净地存储用户数据?能够使用像@login_required这样的装饰器会很好,但只有在匿名用户拥有外部IP时才会重定向。

1 个答案:

答案 0 :(得分:2)

实际上,在每次请求中检查ip似乎是最快的方法之一。考虑到每次请求都已经在内存中加载了ip,您只需要进行简单的字典查找和比较,并使用条件字符串拆分/附加字典查找。与最简单的页面视图中发生的情况相比,性能影响完全可以忽略,并且与使用会话或任何其他机制来保存ip的影响相当。

您可以使用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)

然后只需使用@local_ip_required。请注意,此实现将阻止匿名用户和登录用户从外部位置访问视图。