【问题标题】:Different type of anonymous users with Django不同类型的匿名用户与 Django
【发布时间】:2013-08-13 09:23:45
【问题描述】:

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

我虽然想检查 IP as described here,但在我看来,每次用户加载页面时检查 ip 都很糟糕。

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

【问题讨论】:

标签: django django-authentication anonymous-users


【解决方案1】:

实际上,在我看来,检查每个请求的 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。请注意,此实现将阻止匿名用户和登录用户从外部位置访问视图。

【讨论】:

  • 谢谢,我没有意识到定义装饰器这么容易,我应该可以很容易地适应@authentication_or_local_ip_required。只是一个小细节,在我的例子中,本地 ips 被定义为一组范围,如192.168.1.*,是否有一个简单的快捷方式来测试它,或者我应该实现字符串比较?
  • 有几个IP tool packages。寻找支持范围并提供__contains__ 实现的那些并进行选择。如果您熟悉网络掩码:这就是大多数软件包似乎使用的,而不是通配符。如果你不熟悉:你应该是 :P 但至少python-iptools 支持(('192.168.1.0', '192.168.1.255'),) 形式的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2013-08-02
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
相关资源
最近更新 更多