[英]Authenticate by IP address in Django
我有一個小的Django應用程序,我想限制某些用戶。 來自特定網絡的任何人都應該能夠在沒有任何進一步身份驗證的情況下看到該視圖,僅基於IP地址。 應該要求來自此IP范圍之外的任何其他人使用密碼並根據默認的Django用戶管理進行身份驗證。
我假設我必須為此編寫自定義身份驗證后端,但文檔讓我感到困惑,因為authenticate()
函數似乎需要用戶名/密碼組合或令牌。 我不清楚如何使用IP地址進行身份驗證。
在Django中實現基於IP地址的身份驗證的正確方法是什么? 我寧願盡可能多地使用現有的庫函數來處理與安全相關的代碼,而不是自己編寫所有代碼。
這種身份驗證有兩種合適的方法:
示例中間件可以是:
ALLOWED_IP_BLOCKS = [......]
class NeedToLoginMiddleware(object):
def process_request(self, request):
ip = request.META['REMOTE_ADDR']
if not ip in ALLOWED_IP_BLOCKS: #ip check
if not request.user.is_authenticated(): #if ip check failed, make authentication check
return HttpResponseRedirect(...)
return None
如果您使用的是django身份驗證且REMOTE_ADDR
不在ALLOWED_IP_BLOCKS
列表中,則可以使用is_authenticated
檢查相關用戶是否已登錄。 但是,為了在自定義中間件中使用is_authenticated
,您的自定義中間件必須放在 AuthenticationMiddleware
之后 ,因為request.user
是在該級別上設置的。
MIDDLEWARE_CLASSES = ( ... 'django.contrib.auth.middleware.AuthenticationMiddleware', 'path.to.my.NeedToLoginMiddleware', ... )
request.path
獲取請求URL並檢查請求URL是否需要ip檢查/身份驗證。 有關自定義中間件類的更多信息
您還可以為此目的編寫一個小裝飾器:
def login_by_ip(view_func):
def authorize(request, *args, **kwargs):
user_ip = request.META['REMOTE_ADDR']
for ip in allowedIps.allowedIps:
authenticated_by_ip = re.compile(ip).match(user_ip)
if authenticated_by_ip:
return view_func(request, authenticated_by_ip, *args, **kwargs)
return HttpResponseRedirect('/redirect/path/')
return authorize
allowedIps在我的例子中是一個文件(allowedIps.py),它存儲一個元組中允許的IP的正則表達式,如下所示:
allowedIps = ('^XXX\.XXX\..+\..+$','^XXX\.XXX\.XXX\..+$', '^XXX\.XXX\.XXX\.XXX$')
希望這可以幫助或提出一個想法。 注意:如果將authenticated_by_ip返回到裝飾視圖,則視圖必須接受該參數,如果不需要,也可以省略它。 您還可以更精確地定義正則表達式,以僅接受最多三個數字。
沒有必要為您編寫的用例編寫身份驗證后端。 在中間件層中編寫基於IP的調度程序可能就足夠了
如果您的應用程序的URL匹配,則process_request應檢查經過身份驗證的django用戶並將該用戶與白名單進行匹配。
你可以嘗試這個裝飾。 我測試了它的工作正常:
allowedIps = ['129.0.0.1', '127.0.0.1']
def allow_by_ip(view_func):
def authorize(request, *args, **kwargs):
user_ip = request.META['REMOTE_ADDR']
for ip in allowedIps:
if ip==user_ip:
return view_func(request, *args, **kwargs)
return HttpResponse('Invalid Ip Access!')
return authorize
IMO,如果它是一個小型的非性能關鍵站點,那么用Django解決這個問題就好了。
最好使用Apache或Nginx服務來保護未經授權的用戶。 例如,在Nginx中,我在我的站點配置中有這些行:
include allowed_ips.conf;
deny all;
error_page 403 forbidden.html;
allowed_ips.conf在/ etc / nginx中,看起來像這樣:
allow 110.222.333.222; # J Bloggs (sys admin)
allow 777.222.0.0/16; # Government owned
...
我相信這更好,因為相對緩慢的Django進程永遠不會被阻塞的IP觸及。 如果出於性能或安全原因阻止機器人或其他國家/地區范圍,這一點很重要。
def login_by_id(request):
ip = request.META['REMOTE_ADDR']
try: UserProfile.objects.get(allow_ip=ip)
except UserProfile.DoesNotExist: return HttpResponseRedirect('././')
else:
# auth here
您需要在UserProfile模型中使用allow_ip
,這樣可以節省注冊或更改編輯用戶頁面
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.