- Django REST framework で CORS エラーが出ている…
このような場合の対策をお伝えします。
Django REST framework(以下「DRF」とします)では、外部ライブラリを使うことで簡単に CORS 対策ができます。
本記事では CORS 対策の方法と、そもそも CORS とはどのようなものかをお伝えします。
DRF での CORS 対策の方法
DRF で CORS 対策するのはとても簡単で、以下の流れで行います。
- ライブラリのインストール
- INSTALLED APPS に追記
- ミドルウェアに追記
- CORS ポリシーを追記
ちょっとしたコツもあるので、詳しく解説していきます。
ライブラリのインストール
DRF の CORS 対策用に “django-cors-headers” ライブラリをインストールします。
pip install django-cors-headers
INSTALLED APPS に追記
続いて settings.py の INSTALLED_APPS に django-cors-headers を追記して、Django プロジェクト内で有効化します。
INSTALLED_APPS = [
...
"corsheaders",
...
]
記載する順番はどこでもOKです。
ミドルウェアに追記
この手順では、追記する順番が大事になります。
MIDDLEWARE CommonMiddleware より上に、CorsMiddleware を追記しましょう。
MIDDLEWARE = [
...
"corsheaders.middleware.CorsMiddleware", # 追記
"django.middleware.common.CommonMiddleware", # デフォルトで存在
...
]
Django のミドルウェアは上から順番に処理していきます。
CommonMiddleware は URL の末尾スラッシュの扱いや www の追加などを担当するミドルウェアです。
仮に CorsMiddleware の前に CommonMiddleware が処理されると、CORS ヘッダがレスポンスに付与される前にリダイレクトなどの処理が行われてしまい、CORS ヘッダがうまく付与されない恐れがあります。
そのため、CommonMiddleware の前に CorsMiddleware を記載しておく必要があるのです。
CORS ポリシーを追記
どのドメインからアクセスを許可するかに応じて、大きく次の2パターンの設定方法があります。
- 全てのドメインからのアクセスを許可
- 特定のオリジンからのアクセスのみを許可
いずれかを採用して、settings.py ファイルに追記してください。
全てのドメインからのアクセスを許可
特に制限をかける必要がない場合には、以下のように追記します。
# 全てのオリジンからのアクセスを許可
CORS_ALLOW_ALL_ORIGINS = True
特定のオリジンからのアクセスのみを許可
一方で、特定のオリジンからのアクセスに限定したい場合には、以下のように追記します。
# 許可するオリジンを指定
CORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://sub.example.com",
]
そもそも CORS とは?
CORS(Cross-Origin Resource Sharing)について少し突っ込んでご説明します。
目的はセキュリティ対策
原則として Web ページは、異なるドメインからのアクセスは拒否する仕組みになっています。
もしも異なるドメインからのアクセスをすべて許可してしまうと、悪意のあるクライアントからのアクセスも許すことになってしまい不都合です。
そこで「アクセスを許可したクライアントにだけ CORS ヘッダーを付与する」ことで、API にアクセスできるクライアントを限定することができます。
具体的にはサーバー側で対象のクライアントからのアクセスがあった場合、Access-Control-Allow-Origin という HTTP ヘッダがレスポンスに含まれることになります。
このHTTPヘッダを付与するのに使われるのが、最初にご紹介した “django-cors-headers” ライブラリになります。
まとめ
CORS は API サーバー側でアクセス制限するための仕組みでした。
JavaScript フレームワークと DRF を併用する際によく遭遇する事項になりますので、もし困った場合には今回ご紹介した手順に従って CORS 対策を行ってみてください。
当ブログでは Django や Django REST framework に関する記事を執筆中です。よろしければ他の記事もご覧になってみてください。
コメント