我承認這是一個非常古老的問題,但我使用了一種解決方案,我認爲是更好的,不會危害系統的安全性通過設置ALLOWED_HOSTS = ['*']
。
這是我寫的一箇中間件類,我覺得可以隨意重用。
它繼承自CommonMiddleware
,它是settings.py
的MIDDLEWARE_CLASSES
設置中應該用來代替CommonMiddleware
的人。
from django.middleware.common import CommonMiddleware
from django.conf import settings
from django.http.response import HttpResponse
from django.utils import importlib
class CommonWithAllowedHeartbeatMiddleWare(CommonMiddleware):
"""
A middleware class to take care of LoadBalancers whose HOST headers might change dynamically
but are supposed to only access a specific path that returns a 200-OK status.
This middleware allows these requests to the "heartbeat" path to bypass the ALLOWED_HOSTS mechanism check
without jeopardizing the rest of the framework.
(for more details on ALLOWED_HOSTS setting, see: https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts)
settings.HEARTBEAT_PATH (default: "/heartbeat/"):
This will be the path that is cleared and bypasses the common middleware's ALLOWED_HOSTS check.
settings.HEARTBEAT_METHOD (default: None):
The full path to the method that should be called that checks the status.
This setting allows you to hook a method that will be called that can perform any kind of health checks and return the result.
If no method is specified a simple HttpResponse("OK", status_code=200) will be returned.
The method should expect the HttpRequest object of this request and return either True, False or a HttpResponse object.
- True: middleware will return HttpResponse("OK")
- False: middleware will return HttpResponse("Unhealthy", status_code=503) [status 503 - "Service Unavailable"]
- HttpResponse: middleware will just return the HttpResponse object it got back.
IMPORTANT NOTE:
The method being called and any method it calls, cannot call HttpRequest.get_host().
If they do, the ALLOWED_HOSTS mechanism will be called and SuspeciousOperation exception will be thrown.
"""
def process_request(self, request):
# Checking if the request is for the heartbeat path
if request.path == getattr(settings, "HEARTBEAT_PATH", "/heartbeat/"):
method_path = getattr(settings, "HEARTBEAT_METHOD", None)
# Checking if there is a method that should be called instead of the default HttpResponse
if method_path:
# Getting the module to import and method to call
last_sep = method_path.rfind(".")
module_name = method_path[:last_sep]
method = method_path[(last_sep+1):]
module = importlib.import_module(module_name)
# Calling the desired method
result = getattr(module, method)(request)
# If the result is alreay a HttpResponse object just return it
if isinstance(result, HttpResponse):
return result
# Otherwise, if the result is False, return a 503-response
elif not result:
return HttpResponse("Unhealthy", status_code=503)
# Just return OK
return HttpResponse("OK")
# If this is not a request to the specific heartbeat path, just let the common middleware do its magic
return CommonMiddleware.process_request(self, request)
當然我知道這完全機制繞過CommonMiddleware,但它只有在請求心跳路徑,所以我覺得這是一個小的代價。
希望別人認爲它有用。
這已解決。還有一個settings.py文件覆蓋了以前的django設置文件。 一旦我們在正確的文件中將ALLOWED_HOSTS更新爲['*'],那麼它就起作用了。 – user2653294