CORSについて(1)


CORSとは

EN:Cross-origin resource sharing (CORS)
JA:オリジン間リソース共有

下記サイトではこのように定義されている
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。

補足)originについて
https://developer.mozilla.org/ja/docs/Glossary/Origin


実際触ってみよう

pythonのtornadoというライブラリーを使って、色々検証する
https://www.tornadoweb.org/en/stable/
下記コードをtest.pyに書いて、python test.pyを実行すると、簡易のウェブサーバーが起動される。

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

試しに、ブラウザから設定したURLにアクセスしてみると、無事に表示された。
http://localhost:8888/

開発者ツールのコンソールのところに、試しに下記のコマンドを打ってみると、無事に内容が取得できた。

fetch('http://localhost:8888').then(a => a.text()).then(console.log)

同一オリジンからのgetリクエストなので、取得できるのは当たり前のような感じだね。

Googleのホームページを開いて、同じことをやったら、どうなるかを検証してみよう。
取得できなかった。

クロスオリジン要求をブロックしました: 
同一生成元ポリシーにより、http://localhost:8888/ にあるリモートリソースの読み込みは拒否されます 
(理由: CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない)。

リクエストに'Access-Control-Allow-Origin'の指定が必要であることが分かった。

test.pyのgetに下の一行を足して、プログラムを再起動してみた。

self.add_header("Access-Control-Allow-Origin","https://www.google.com")

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.add_header("Access-Control-Allow-Origin","https://www.google.com")
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

前と同じように、googleからgetのリクエストを送ってみると、無事テキストを取得できるようになった

つまり、オリジンAからオリジンBへ何かしらのリクエストを送る時、オリジンB側でオリジンAからのリクエストを許可する設定をしない限り、オリジンAからオリジンBの内容を取得することができない。

逆に言うと、オリジンB側でオリジンAからのリクエストに対して事前許可してあげると、オリジンAからオリジンBのコンテンツを取得できるようになるってことだ。

今回のまとめ

1.CORSはオリジン間リソース共有の時に使うポリシー的なもの
2.訪問先のオリジン側で事前にAccess-Control-Allow-Originを設定しておくと、訪問元のオリジンから訪問先のリソースを取得できるが、設定がない場合、取得できない。