LoginSignup
9
9

More than 5 years have passed since last update.

Amazon API GatewayをCross-Originで利用する設定、Cross-Originせずに利用する設定のまとめ

Posted at

Amazon API Gatewayを利用し、AWS Lambda関数をAPIとして公開する事が出来ますが、公開したAPIをAjaxで利用する場合、Cross-Originでアクセスするケースが出てきます。
※ Cross-Originにしないでアクセスする事もできますが、そちらは後述します。

対応を行う際にいろいろ調べたので、まとめとして書いてみます。

CORSでAPIを利用する

API GatewayリソースのCORSを有効にする

API Gatewayの設定については開発者リファレンスに記載されています。
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html

一部引用します

Lambda または HTTP の プロキシ統合の場合、OPTIONS レスポンスヘッダーを API Gateway から設定できます。ただし、プロキシ統合では統合レスポンスが使えないので、Access-Control-Allow-Origin ヘッダーを返すにはバックエンドに依存する必要があります。

私の解釈としては以下の通りです。
image020.png

1.AjaxでAPI Gatewayを利用するHTMLコンテンツを取得します。
このドメインはAPI Gatewayとドメインが異なるため、APIを利用するとCross-Originになります。

2.preflightリクエストを送信します。
Cross-Originのアクセスになるため、preflightリクエストを送信しますが、preflightリクエストを送るか否かについてブラウザに依存するそうです。(ChromeとIE11で動作が異なる為、少しハマりました)
preflightはOPTIONSでリクエストされ、Mock エンドポイントがレスポンスします。

3.preflightリクエストが成功するとAPIを呼び出します。このレスポンスにもAccess-Control-Allow-Originヘッダーが必要になります。

開発者ガイドに記載されている

Access-Control-Allow-Origin ヘッダーを返すにはバックエンドに依存する必要があります

というのはLambdaの処理(=バックエンド)でレスポンスヘッダーを設定してくださいという解釈をしました。

具体的には以下の実装になります

def respond(err, res=None):
    return {
        'statusCode': '400' if err else '200',
        'body': err if err else json.dumps(res, cls=DecimalEncoder),
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin' : '*'
        },
    }

CORSで利用する場合の設定はこれでおしまいです。

CORSを有効にしないでAPIを使う

Access-Control-Allow-Origin : * を設定したくない。また、*の代わりにドメイン指定するのも煩雑だという考えもあると思います。
その場合はCross-Originにならない場所からAPIを利用する事で、CORSを有効にする必要が無くなります。

こんなイメージです。

image033.png

設定方法としては「HTTP プロキシ統合」が参考になります。
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html

具体的にはLambda関数を公開しているAPIと同じAPIにHTTPプロキシのリソースを作成し、HTMLコンテンツをProxyします。
エンドポイントURLの場所がHTMLコンテンツの置き場です。

HTTP_PROXY.png
注意点としては、APIの直下にhtmlという子リソースを作り、その下にプロキシリソース{proxy+}を作成しています。{proxy+}はパターン一致でProxyするので「html」のリソースを1階層はさまないとreadやwriteのLambda関数に対するリクエストもHTTP Proxyに流れてしまうと考えたからです。

以上の設定を行う事で、Cross-Originにしないで利用できるようになりました。

HTTP ProxyするとHTMLとJSはProxyされるがimageファイルが壊れる?

おまけですが、HTMLコンテンツをHTML Proxyで表示させた際にimageファイルが壊れてしまいました。
※HTTP Statusは200で返りますが、ブラウザで表示できない状態になります。

この事象は「バイナリサポート」を設定することで解消します。(API Gatewayのお作法のようですね)
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-payload-encodings.html

API GW.png

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9