django-cors-headers介紹
一個Django應用程序,向響應頭中添加跨域資源共享(CORS)頭。這允許從其他來源向Django應用程序發出瀏覽器內請求,當然也可以自定義中間件然后添加響應頭信息。
關於cors問題可點擊此處
安裝
pip install django-cors-headers
注冊到settings.py中的應用中
INSTALLED_APPS = [
...
'corsheaders' ,
...
]
添加一個中間件類來監聽響應
MIDDLEWARE = [ # 或Django <1.10上的MIDDLEWARE_CLASSES
...
'corsheaders.middleware.CorsMiddleware' ,
'django.middleware.common.CommonMiddleware' ,
...
]
應將Corsmidlware放置在盡可能高的位置,尤其是要放在能夠生成響應的中間件之前,比如Django的CommonMiddleware或Whitenoise middleware。如果不是放在這些響應中間件之前,它可能無法將CORS頭添加到這些響應中。
另外,如果您使用CORS_REPLACE_HTTPS_REFERER,它應該放在Django的CsrfViewMiddleware之前。
配置
在Django設置中配置中間件的行為。您必須將允許進行跨站點請求的主機添加到 CORS_ORIGIN_WHITELIST
,或將CORS_ORIGIN_ALLOW_ALL
設置為True
以允許所有主機。
CORS_ORIGIN_ALLOW_ALL
如果為True
,將不使用白名單,並且將接受所有來源。默認為False
。
CORS_ORIGIN_WHITELIST
授權進行跨站點HTTP請求的來源列表。默認為[]
。
CORS_ORIGIN_WHITELIST = [
'https://example.com' ,
'https://sub.example.com' ,
'http:// localhost:8080' ,
'http://127.0.0.1:9000'
]
CORS_ORIGIN_REGEX_WHITELIST
代表正則表達式的字符串列表,這些正則表達式與被授權發出跨站點HTTP請求的Origins相匹配。默認為[]
。當 CORS_ORIGIN_WHITELIST
不切實際時(例如您擁有大量子域時)很有用。
CORS_ORIGIN_REGEX_WHITELIST = [
r “ ^ https:// \ w + \ .example \ .com $” ,
]
以下參數是可選的。
CORS_URLS_REGEX
一個正則表達式,用於限制將發送CORS標頭的URL。默認為r'^。* $'
,即匹配所有URL。當您僅在網站的一部分上需要CORS時很有用,例如/ api /
處的API
CORS_URLS_REGEX = r '^ / api /.*$'
CORS_ALLOW_METHODS
實際請求所允許的請求方式列表。默認為:
CORS_ALLOW_METHODS = [
'DELETE' ,
'GET' ,
'OPTIONS' ,
'PATCH' ,
'POST' ,
'PUT' ,
]
可以將默認值導入為corsheaders.defaults.default_methods,
因此您可以使用自定義方法對其進行擴展。這使您可以隨時了解最新更改。例如:
from corsheaders.defaults import default_methods
CORS_ALLOW_METHODS = list(default_methods) + [
'POKE',
]
CORS_ALLOW_HEADERS
發出實際請求時可以使用的非標准HTTP標頭的列表。默認為:
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
可以將默認值導入為corsheaders.defaults.default_headers,
以便您可以使用自定義標頭對其進行擴展。這使您可以隨時了解最新更改。例如:
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = list(default_headers) + [
'my-custom-header',
]
CORS_EXPOSE_HEADERS
The list of HTTP headers that are to be exposed to the browser. Defaults to []
.
CORS_PREFLIGHT_MAX_AGE
客戶端/瀏覽器可以緩存預檢響應的秒數。 如果該值為0(或任何錯誤值),則不會發送最大期限標頭。 默認為86400(一天)。
注意:預檢請求是在發出“復雜請求”(例如Content-Type不是application / x-www-form-urlencoded)時提出的額外請求,用於確定服務器實際接受的請求。
CORS_ALLOW_CREDENTIALS
如果為True
,則將允許將cookie包含在跨站點HTTP請求中。默認為False
。
注意:在Django 2.1中,添加了SESSION_COOKIE_SAMESITE設置,默認情況下設置為 Lax
,這將防止Django的會話Cookie跨域發送。將其更改為‘ None
’可繞過此安全限制。
CSRF集成
大多數站點將需要利用Django提供的跨站點請求偽造保護。CORS和CSRF是分開的,並且Django無法使用您的CORS配置免除“ Referer ”中的網站,以檢查它是否處理了安全請求。做到這一點的方法是使用其CSRF_TRUSTED_ORIGINS設置。例如:
CORS_ORIGIN_WHITELIST = [
'http://read.only.com',
'http://change.allowed.com',
]
CSRF_TRUSTED_ORIGINS = [
'change.allowed.com',
]
CORS_REPLACE_HTTPS_REFERER
CSRF_TRUSTED_ORIGINS
是Django 1.9中引入的,因此早期版本的用戶將需要替代解決方案。如果CORS_REPLACE_HTTPS_REFERER
為 True
,則只要CORS檢查通過,CorsMiddleware
就會將Referer
標頭更改為將通過Django的CSRF檢查的內容。默認為 False
。
請注意,與CSRF_TRUSTED_ORIGINS
不同,此設置不允許您區分CORS 信任讀取資源的域和避免CSRF保護而信任更改資源的域。
啟用此功能后,您還應該在MIDDLEWARE_CLASSES中的django.middleware.csrf.CsrfViewMiddleware之后添加corsheaders.middleware.CorsPostCsrfMiddleware來撤消Referer
MIDDLEWARE_CLASSES = [
...
'corsheaders.middleware.CorsMiddleware' ,
...
'django.middleware.csrf.CsrfViewMiddleware' ,
'corsheaders.middleware.CorsPostCsrfMiddleware' ,
...
]
Signals
如果您的用例需要的不僅僅是上述配置,那么您可以附加代碼來檢查是否應該允許給定的請求。例如,這可用於讀取模型允許的來源列表。將任意數量的處理程序附加到啟用check_request_enabled的Django信號上,該信號提供request
參數(在處理程序中使用** kwargs
防止將來添加任何參數)。如果附加到信號的任何處理程序返回truthy值,則將允許該請求。
例如,您可以定義如下處理程序:
# myapp/handlers.py
from corsheaders.signals import check_request_enabled
from myapp.models import MySite
def cors_allow_mysites(sender, request, **kwargs):
return MySite.objects.filter(host=request.host).exists()
check_request_enabled.connect(cors_allow_mysites)
然后在應用就緒時使用Django AppConfig連接它:
# myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
# myapp/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
# Makes sure all signal handlers are connected
from myapp import handlers # noqa
信號的常見用例是允許所有來源訪問URL的子集,同時允許一組正常的來源訪問所有 URL。僅使用常規配置是不可能的,但是可以使用信號處理程序來實現。
首先將CORS_ORIGIN_WHITELIST
設置為允許訪問每個URL的受信任來源列表,然后將處理程序添加到 check_request_enabled
以允許CORS不受限制URL的來源。例如:
# myapp/handlers.py
from corsheaders.signals import check_request_enabled
def cors_allow_api_to_everyone(sender, request, **kwargs):
return request.path.startswith('/api/')
check_request_enabled.connect(cors_allow_api_to_everyone)