我目前正在从事的 Django 项目是一个应该从本地网络和 Internet 访问的网站。只有当从本地网络访问站点时,部分内容才应该对匿名用户可用(基本上是对 IP 地址的测试),而经过身份验证的用户可以访问整个内容。
我虽然要按照此处所述检查 IP ,但在我看来,每次用户加载页面时检查 ip 都非常糟糕。
即使是匿名用户,有没有办法干净地存储用户数据?能够使用像这样的装饰器会很好@login_required
,但只有当匿名用户具有外部 IP 时才会重定向。
我目前正在从事的 Django 项目是一个应该从本地网络和 Internet 访问的网站。只有当从本地网络访问站点时,部分内容才应该对匿名用户可用(基本上是对 IP 地址的测试),而经过身份验证的用户可以访问整个内容。
我虽然要按照此处所述检查 IP ,但在我看来,每次用户加载页面时检查 ip 都非常糟糕。
即使是匿名用户,有没有办法干净地存储用户数据?能够使用像这样的装饰器会很好@login_required
,但只有当匿名用户具有外部 IP 时才会重定向。
实际上,在我看来,检查每个请求的 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。请注意,此实现将阻止匿名用户和登录用户从外部位置访问视图。