はじめに
初投稿です!CORSを理解したいと思い調べていくうちに記事にしたいと思った次第です。初学者向けに書いた記事になります。
同一オリジンについて
CORSの理解を深めるために同一オリジンについて意味を確認しましょう。
・オリジンとは
スキーム(httpsなどのプロトコル)、ホスト(ドメイン)、ポート番号のことです。
ある二つのページのオリジンが等しければ、両者のオリジンは等しいです。これは、セキュリティ上安全性を高めるための方法であり、同一オリジンポリシーと呼ばれます。反対に異なるオリジンであることをクロスオリジンといいます。あるページを見ているときに、そのぺージのリソースとオリジンが同じ場合は同一オリジン、見ているページと対象のリソースが異なる場合はクロスオリジンということになります。具体的な例では、あるページから他のAPIにアクセスする場合が挙げられます。
実際にFlaskでサンプルを作ってみましょう。
from app import app
if __name__ == "__main__":
app.run()
from flask import Flask
app = Flask(__name__)
@app.route("/")
def helloWorld():
return "Hello, Closed World!"
python run.py
で実行すると、ローカルサーバーが立ち上がり「Hello, Closed World!」と表示されると思います。続いて、次のようなhtmlファイルを作成してみましょう。
<!DOCTYPE html>
<html>
<head>
<title>CORS Test</title>
</head>
<body>
<button id="fetchButton">Fetch Data</button>
<script>
document.getElementById('fetchButton').addEventListener('click', fetchData);
function fetchData() {
fetch('FlaskアプリのURLを指定') // ローカルホストの場合http://localhost:5000/
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}
</script>
</body>
</html>
fetchする対象(リソース)とローカルホストで実行したファイルが一致していますが、malicious.htmlのドメインはflaskアプリのURLとは異なっています。これがクロスオリジンです。ローカルホストが実行しているときに、htmlファイルを開きfetchボタンを押すと、ローカルホストの方でステータスが200となっていることからリクエストが成功していることが分かります。
今度は、flask_corsを利用して、アクセス制限をかけてみましょう。
from flask_cors import CORS
cors = CORS(app, resources={r'/': {'origins': 'http://127.0.0.1:5000'}})
上記2行app.pyに追加します。
①先ほど作ったmalicious.htmlをflaskアプリの別のディレクトリに移動するなどしてディレクトリを分けましょう。
②ターミナルで移動したディレクトリを開き、
python -m http.server 5001
と入力し、別のポートのローカルサーバーを立ち上げます。
③立ち上げたローカルホスト(5001)+malicious.htmlを開きます。
④fetchをクリック
すると、何もflask側のターミナルの方には表示されないはずです。
検証ツールを使って、htmlのコンソールを見てみましょう。
すると、
'malicious.html' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
というエラーが出ていると思います。CORSによってflaskアプリへのアクセスが制限されていることが確認できました。
flaskでCORSを実装する方法について簡単にご紹介させていただきました。
もし誤り等ございましたらコメントいただけると幸いです。
参考資料
https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy(同一オリジンポリシー)
https://www.youtube.com/watch?v=7wmqbg1W8u0(コードマフィアさんのCORS説明)
https://flask-cors.readthedocs.io/en/latest/(Flask_Cors)