SE_BOKUのITな日常

SE_BOKUが知ってること・勉強したこと・考えたことetc

オリジン間リソース共有とCORS対策とDjango REST Framework (DRF)での設定例

f:id:arakan_no_boku:20190607195913j:plain

目次

オリジン間リソース共有

ブラウザは今表示しようとしているHTMLをとってきたサーバー(オリジン)と、違うサーバー(オリジン)とでデータ共有しようとすると拒否するように動きます。

怪しいページを読み込んだ時、裏でJavaScriptが動いて、イントラネット内のサーバーのデータを抜き取るようなことが簡単にできては困るので、セキュリティの確保のためには絶対必要な機能です。

ちなみにオリジンが同一であるというのは。

  • URLのFQDNが一致している
  • スキーム(プロトコル)が一致している
  • ポート番号が一致している

ということを意味します。

FQDNは「ホスト名+ドメイン名」なので、例えば「www」と言うホスト名、「exsample.com」というドメイン名で、「www.exsample.com」がFQDNです。

で・・、プロトコルは「http」とかのこと。

ようするに「https://www.exsample.com:8000」まで一致すれば同じとみなすという風に理解しとけばいいと思います。 

CORS(Cross-Origin Resource Sharing)

ただ、JavaScriptで外部のデータを参照することが必要なケースはあります。

Web-Apiなどで、外部のサーバーから情報を取得して何等かの処理をするとかです。

Web APIは、依頼内容をHTTPリクエストの形で送信すると、処理結果がHTTPレスポンスの形で送られてくるものなので、必ず、クロスオリジンになります。

なので、結果を受け取る側でエラーにならないように、オリジンの異なるサーバーからデータを取得することができる仕組みが必要になります。

それが「CORS(Cross-Origin Resource Sharing)」です。

日本語でいえば「オリジン間リソース共有」対策です。

 

CORSを有効にする2つの方法

CORSを有効にする方法には2通りあります。

  • WHITELIST方式
  • CORS_ORIGIN_ALLOW_ALL =Trueにする方式

です。

WHITELIST方式

WHITELIST方式は、あらかじめ「安全な対象」をリストへ定義しておくやり方です。

WHITELIST方式を使うには、「http://」または「https://」のプロトコルの指定が必ず必要で、これがないと以下のようなエラーがでます。

Origin '127.0.0.1:3000' in CORS_ORIGIN_WHITELIST is missing scheme or netloc

以前はそうでなかったのか、http://のついていないサンプルが多くネットにはあがってますし、情報も少なくて、意外とハマるので注意が必要です。

github.com 

CORS_ORIGIN_ALLOW_ALL =Trueにする方式

CORS_ORIGIN_ALLOW_ALLは、ようするに全部OKにするということです。

これは、かなり緩いですし、テストとかデモとかでなくえれば、フリーアクセスのAPIを公開するとかみたいな、セキュリティをあまり考えなくていい用途にしか使えないと思います。

クロスオリジンを許す必要があるURLをほぼ特定できる場合には、より安全な「WHITELIST方式」にするのがよいと思います。

Django REST Framework (DRF)でCORSの設定サンプル

PythonDjangoにはWebAPI作成フレームワークDjango REST Framework (以後、DRF)」 があります。

DRFでCORS対策モジュールを使えるようにする設定の例だけ書いておきます。

djangoプロジェクトで REST Framework +Cors対策の「settings.py」の設定例です。

INSTALLED_APPS = [
    'rest_framework',
    'corsheaders',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ]
}

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
]

#CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000',
'http://127.0.0.1:3000',
)

 

なお、上記は、Windows10で、Anaconda・Djangoがインストールされている環境がベースです。

以下にインストールがまだの場合の、インストール例を書いておきます。
CORS対策モジュールのインストール。。

pip install django-cors-headers

RESTフレームワークのインストール。

pip install djangorestframework 

WebApiを処理するための「requests」のインストール。

pip install requests

ではでは。