GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

ottoyiu

django-cors-headers – Cross-Origin Resource Sharing(CORS)に必要なサーバヘッダを処理するDjangoアプ..

投稿日:

Cross-Origin Resource Sharing(CORS)に必要なサーバヘッダを処理するDjangoアプリケーション

django-cors-headers

CORS(Cross-Origin Resource Sharing)ヘッダーをレスポンスに追加するDjango App。

JSON-Pは便利ですが、厳密にはGETリクエストに限定されています。 CORSはXmlHttpRequest上に構築されており、開発者は同じドメイン要求と同様にクロスドメイン要求を行うことができます。 詳細はこちら: http : //www.html5rocks.com/jp/tutorials/cors/

要件

すべての組み合わせでテスト:

  • Python:2.7、3.6
  • Django:1.8,1.9,1.10,1.11,2.0

セットアップ

pipからインストールする:

pip install django-cors-headers

インストールしたアプリに追加してください:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

また、レスポンスを聞くためにミドルウェアクラスを追加する必要があります:

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

CorsMiddlewareは、特にDjangoのCommonMiddlewareやWhitenoiseのWhiteNoiseMiddlewareなどのレスポンスを生成できるミドルウェアの前に、できるだけ高い位置に配置する必要があります。 前になければ、CORSヘッダーをこれらの応答に追加することはできません。

また、 CORS_REPLACE_HTTPS_REFERERを使用している場合は、DjangoのCsrfViewMiddleware前に配置する必要があります(下記参照)。

構成

Djangoの設定でミドルウェアの動作を設定します。 クロスサイト要求を許可するホストをCORS_ORIGIN_ALLOW_ALLするか、 CORS_ORIGIN_ALLOW_ALLTrueに設定してすべてのホストを許可する必要があります。

CORS_ORIGIN_ALLOW_ALL

True場合、ホワイトリストは使用されず、すべての起源が受け入れられます。 デフォルトはFalseです。

CORS_ORIGIN_WHITELIST

クロスサイトHTTP要求を行うことが許可されているオリジンホスト名のリスト。 'null'は、このリストにも表示され、クライアントがfile://ドメインから実行している場合など、 「プライバシーに敏感なコンテキスト」で使用されるOrigin: nullヘッダーと一致します。 デフォルトは[]です。

例:

CORS_ORIGIN_WHITELIST = (
    'google.com',
    'hostname.example.com',
    'localhost:8000',
    '127.0.0.1:9000'
)

CORS_ORIGIN_REGEX_WHITELIST

クロスサイトHTTPリクエストの作成を許可されているオリジンホスト名の原点regexリストと一致する正規表現のリスト。 デフォルトは[]です。 サブドメインが多数ある場合など、 CORS_ORIGIN_WHITELISTが実用的でない場合に役立ちます。

例:

CORS_ORIGIN_REGEX_WHITELIST = (r'^(https?://)?(\w+\.)?google\.com$', )

以下は省略可能な設定であり、おそらくデフォルトで十分です。

CORS_URLS_REGEX

CORSヘッダーが送信されるURLを制限する正規表現です。 デフォルトはr'^.*$'つまり、すべてのURLに一致します。 あなたのサイトの一部でCORSだけが必要なとき、例えば/api/ APIなどのときに便利です。

例:

CORS_URLS_REGEX = r'^/api/.*$'

CORS_ALLOW_METHODS

実際の要求に対して許可されるHTTP動詞のリスト。 デフォルトは次のとおりです。

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

デフォルトはcorsheaders.defaults.default_methodsとしてcorsheaders.defaults.default_methodsすることができます。カスタムメソッドで拡張することができます。 これにより、今後の変更を常に最新の状態に保つことができます。 例えば:

from corsheaders.defaults import default_methods

CORS_ALLOW_METHODS = 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としてcorsheaders.defaults.default_headersすることができ、カスタムヘッダーで拡張することができます。 これにより、今後の変更を常に最新の状態に保つことができます。 例えば:

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
    'my-custom-header',
)

CORS_EXPOSE_HEADERS

ブラウザーに公開されるHTTPヘッダーのリスト。 デフォルトは[]です。

CORS_PREFLIGHT_MAX_AGE

クライアント/ブラウザがプリフライト応答をキャッシュできる秒数。 これが0(または偽の値)の場合、最大の年齢ヘッダーは送信されません。 デフォルトは86400 (1日)です。

注:プリフライト要求は、サーバが実際に受け入れる要求を判断するために、 “単純ではない”要求( Content-Typeapplication/x-www-form-urlencodedはない)を行うときに行われる余分な要求です。 HTML 5 Rocks CORSチュートリアルでそれについてもっと読む。

CORS_ALLOW_CREDENTIALS

True場合、クロスサイトHTTP要求にCookieを含めることが許可されます。 デフォルトはFalseです。

CORS_MODEL

これが設定されている場合は、 app.modelnameの形式で許可された起点を調べるモデルのパスにする必要があります。 デフォルトはNoneです。

モデルはcorsheaders.models.AbstractCorsModelから継承し、 corsheaders.models.AbstractCorsModelというCharField許可された起点を指定する必要があります。

CSRF統合

ほとんどのサイトでは、Djangoが提供するクロスサイトリクエスト偽造の保護を利用する必要があります。 CORSとCSRFは別々のもので、DjangoはあなたのCORS設定を使ってRefererから安全なリクエストであることを確認するサイトを免除する方法がありません。 これを行う方法は、 CSRF_TRUSTED_ORIGINSの設定です。 例えば:

CORS_ORIGIN_WHITELIST = (
    'read.only.com',
    'change.allowed.com',
)

CSRF_TRUSTED_ORIGINS = (
    'change.allowed.com',
)

CORS_REPLACE_HTTPS_REFERER

CSRF_TRUSTED_ORIGINSはDjango 1.9で導入されました。以前のバージョンのユーザーには、代わりの解決策が必要です。 CORS_REPLACE_HTTPS_REFERERTrue場合、 CORS_REPLACE_HTTPS_REFERERRefererヘッダーをCORSチェックが成功するたびにDjangoのCSRFチェックに渡すものに変更します。 デフォルトはFalseです。

CSRF_TRUSTED_ORIGINSとは異なり、この設定では、CORSによってリソースを読み取ることが信頼されるドメインと、CSRF保護を回避してリソースを変更することが信頼されるドメインとを区別することはできません。

この機能を有効にすると、あなたのMIDDLEWARE_CLASSEScorsheaders.middleware.CorsPostCsrfMiddleware後にdjango.middleware.csrf.CsrfViewMiddlewareを追加してReferer置換を元に戻すdjango.middleware.csrf.CsrfViewMiddlewareがあります:

MIDDLEWARE_CLASSES = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    'corsheaders.middleware.CorsPostCsrfMiddleware',
    ...
]

信号

上記の設定以上のものを必要とするユースケースがある場合は、コードを添付して、特定の要求を許可する必要があるかどうかを確認できます。 たとえば、モデルから許可する起点のリストを読み取るために使用できます。 任意の数のハンドラをcheck_request_enabled Djangoシグナルに接続します。これはrequest引数を提供します(将来の引数が追加されないようにするにはハンドラで**kwargsを使用します)。 シグナルに添付されたハンドラがtrue値を返す場合、その要求は許可されます。

たとえば、次のようなハンドラを定義することができます。

# myapp/handlers.py
from corsheaders.signals import check_request_enabled

from .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 . import handlers  # noqa

シグナルの一般的な使用例は、 すべての起点がURLのサブセットにアクセスできるようにする一方で、通常の起点セットがすべての URLにアクセスできるようにすることです。 これは通常の設定だけでは不可能ですが、シグナルハンドラで実現できます。

最初にCORS_ORIGIN_WHITELISTをすべてのURLにアクセスできる信頼できる起点のリストに設定し、 CORS_ORIGIN_WHITELISTにハンドラを追加して、無制限のURLの起点に関係なくCORSを許可します。 例えば:

# 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)

クレジット

django-cors-headersはOtto Yiu( @ottoyiu )によって作成され、 25人以上の貢献者によって開発されました。 すべての寄稿者のおかげで、あなたが関与したいのであれば、躊躇しないでください。







-ottoyiu

執筆者: