概要
公式サイトにおける Sandboxes の CORS Filter を試してみたので、メモがてら記事を投稿します。
検証環境
-
macOS - High Sierra 10.13.6
-
Docker - 18.06.1-ce
-
Docker Machine - 0.15.0
-
Docker Compose - 1.22.0
事前準備
envoy のリポジトリをクローンしておく必要があります。
Sandbox の構築
基本的にドキュメント通りです。
ターミナルを2つ起動した後、それぞれのターミナルで次のコマンドを実行します。
$ docker-machine create --driver virtualbox frontend
$ eval $(docker-machine env frontend)
$ docker-machine create --driver virtualbox backend
$ eval $(docker-machine env backend)
クローンした envoy リポジトリの examples/cors/frontend ディレクトリと examples/cors/backend ディレクトリに格納されている各 docker-compose.yml からサービスを開始します。
$ cd envoy/examples/cors/frontend
$ docker-compose up --build -d
$ cd envoy/examples/cors/backend
$ docker-compose up --build -d
これで Sandbox の構築は完了です。
frontend を通じて backend へリクエストを送信する。
Sandbox を作成すると仮想マシンの IP とサービスへ割り当てられている IP を用いることで frontend のサービスへアクセスできます。
まず、仮想マシンの IP 確認します。
$ docker-machine ip frontend
192.168.99.100
frontend のアプリ動作に backend の仮想マシンのIPも必要となるため、このタイミングで調べておきます。
$ docker-machine ip frontend
192.168.99.101
次にサービスへ割り当てられているポートを確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
897e22a5cec3 frontend_frontend-service "/bin/sh -c /usr/loc…" 2 hours ago Up 2hours 80/tcp, 10000/tcp frontend_frontend-service_1
c07e94bee417 frontend_front-envoy "/docker-entrypoint.…" 2 hours ago Up 2hours 0.0.0.0:8001->8001/tcp, 10000/tcp, 0.0.0.0:8000->80/tcp frontend_front-envoy_1
私の環境では frontend アプリのURLは http://192.168.99.100:8000/
となっていたため、ブラウザからアクセスしてみます。すると次のような画面が表示されます。ちなみに 8001 番ポートは envoy の admin へアクセスすることができました。
あとは Remote IP
となっている箇所へ backend が動作する仮想マシンの IP を入力した後、Fetch asset
を押すだけです。CORS Enforcement
を切り替えることにより、CORS Filter が無効な URL
、あらゆる origin が有効な URL
、そして特定の origin のみを許可する URL
とリクエストの送信先を切り替えることができます。
curl を用いて backend へリクエストを送信する。
前述の通り、frontend のアプリは backend の URL を切り替えることにより、CORS Filter の設定値が異なる URL へリクエストを送信しています。従って、 curl
により直接リクエストを送ることにより、レスポンスヘッダーの内容を確認することも可能です。
backend における各 URL とそれぞれのCORSの設定はenvoyリポジトリの examples/cors/backend/front-envoy.yaml から確認できます。
$ yq -y '.static_resources.listeners[].filter_chains[].filters[].config.route_config' front-envoy.yaml
name: local_route
virtual_hosts:
- name: services
domains:
- '*'
cors:
allow_origin:
- '*'
allow_methods: GET
routes:
- match:
prefix: /cors/open
route:
cluster: backend_service
- match:
prefix: /cors/disabled
route:
cluster: backend_service
cors:
enabled: false
- match:
prefix: /cors/restricted
route:
cluster: backend_service
cors:
allow_origin:
- envoyproxy.io
allow_methods: GET
- match:
prefix: /
route:
cluster: backend_service
API ドキュメントから各設定値を確認すると CORS Filter が有効となっているパスは /cors/open
と /cors/restricted
であるとわかります。そして CORS Filter が無効となっているパスは /cors/disabled
だとわかります。
/cors/open
へリクエストを送信してみます。
$ curl -I http://192.168.99.101:8000/cors/open -H 'Origin: https://foo.com'
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 8
server: envoy
date: Fri, 04 Jan 2019 15:04:03 GMT
x-envoy-upstream-service-time: 1
access-control-allow-origin: https://foo.com
レスポンスヘッダへ access-control-allow-origin
が付加されていることが確認できました。
次に /cors/disabled
へリクエストを送信してみます。
$ curl -I http://192.168.99.101:8000/cors/disabled -H 'Origin: https
://foo.com'
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 8
server: envoy
date: Fri, 04 Jan 2019 15:05:44 GMT
x-envoy-upstream-service-time: 2
レスポンスヘッダへ access-control-allow-origin
が付加されていないことが確認できます。