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