開発時にクロスドメインAPIと戦う CORS

  • 5
    Like
  • 0
    Comment

Webアプリを開発時に、クロスドメイン制約でAPIと通信が出来なかったので、開発環境側で対応する方法を考えて見ました。
外部公開用のAPIであれば、サーバー側でCORS仕様に対応する必要があるのでさっさと対応してもらいましょう。
→外部公開のAPIサービス見た所 Originを超えたアクセスを許可するヘッダーを返しているサービスが見当たらずJSONP等の対応が多いように感じました。
今回の場合では、運用環境ではAPIとWebアプリは同じドメイン上に存在し、開発時にlocalhostとAPIでクロスドメインになってしまうというパターンです。

どうやって対応するの?

Web Debugging Proxy を使うか SPA開発時に利用するビルドツールの proxy 機能を利用します。

  • Fiddler (Windowsのみ, 無料)
  • Charles (Windows/Mac/Linux, 有料 試用期間あり)
  • Webpack (node.jsが使える環境)

Web Debugging Proxy を利用して、サーバーからのレスポンスヘッダーに情報を付加

Webサーバ側からのレスポンスに、Originを越えたアクセスを許可するヘッダーを付加します。
レスポンスのヘッダーに下記の情報を付加するように、Web Debugging Proxyの設定を行います。

Access-Control-Allow-Origin: *

Fiddler

  1. メニューバーから 「Rules」→「Customize Rules..」 を選択
  2. ファイルが開きます。 (下記にファイルが作成されます。)
    C:\Users\ユーザ名\Documents\Fiddler2\Scripts\CustomRules.js
  3. ファイル内のコードに1行追加します。
static function OnBeforeResponse(oSession: Session) {
    if (m_Hide304s && oSession.responseCode == 304) {
        oSession["ui-hide"] = "true";
    }
    oSession.oResponse["Access-Control-Allow-Origin"] = "*";   // ← この行を追加
}

Fiddlerを立ち上げた状態であれば、全てのレスポンスにヘッダーが付加されます。
セキュリティ的にあまり好ましい状態ではないと思うので、検証が終わったらファイルは削除する方が良いかと思います。
ヘッダーを付加するドメインを制限する等も設定できます。

Charles

  1. メニューバーから 「Tools」→「Rewrite...」 を選択
  2. 「Rewrite Settings」 画面が表示される。
  3. 「Enable Rewrite」 のチェックボックスをチェック
  4. 「Add」 ボタンを押下
  5. 右側に画面が表示される
  6. 右側の 「Name: 」 に適当名前を設置
  7. 右側の中段 「Add」 ボタンを押下
  8. 「Edit Location」 画面が表示されるので「OK」ボタンを押下
  9. 右側の下段 「Add」 ボタンを押下
  10. 「Rewrite Rule」 画面が表示される
  11. Type: 「Add Header」 を選択
  12. Where: 「Request」のチェックを外して、「Response」にチェックを入れる。
  13. Replace: 「Name」 に 「Access-Control-Allow-Origin」 を追記
  14. Replace: 「Value」 に 「*」 を追記
  15. Replace all ラジオボタンをチェック
  16. 「Rewrite Rule」 画面の「OK」ボタンを押下
  17. 「Rewrite Settings」 画面の「OK」ボタンを押下

1.png 
2.png

ビルドツールの proxy 機能を利用

Webpackを利用している場合は、APIサーバーをProxyする機能を利用します。1 2

webpack.config.js
devServer: {
  proxy: {
    '/api/*': {
      target: 'http://example.com',
      secure: false
    }
  }
}

注意事項

CORSまとめ さらに手の込んだHTTP通信を使いたい場合 から引用

CORSの仕様では、次の条件に一つでも当てはまる場合は、実際のHTTPリクエスト(GETやPOST)を行う前に、preflight requestとしてOPTIONSリクエストを行うことが定められています。この場合、サーバ側ではGETやPOSTに加えてOPTIONSでも同様のCORS対応が必要になりますので、注意が必要です。

  • HTTPリクエストのメソッドがGET, POST, HEAD以外である。
  • HTTPリクエストヘッダにAccept, Accept-Language, Content-Language以外のフィールドが含まれている、あるいは、Content-Typeフィールドにapplication/x-www-form-urlencoded, multipart/form-data, text/plain以外の内容が指定されている。

JSONでリクエストする場合は、Content-Typeが「application/json」になるので、CORS仕様としてpreflight requestが必要になります。
しかし、下記のライブラリでは、CORS仕様を厳密に実装されていないようで、「Access-Control-Allow-Origin」ヘッダーが返されると通信は可能でした。

  • Jquery
  • axios

Fetch API については、CORS仕様を厳密に実装されているので、preflight requestの手続きが必要になります。