こんばんは。今日は、Microsoft AzureのAPI Managementに関するトラブルシューティングです。(エラー自体は、API ManagementのAPIに限らず一般的なものですが、解決するための設定方法などはAPI Management固有の手順になります)
解決に時間がかかってしまいましたがCORSをちゃんと理解する良い機会になりました。
それでは早速参ります。
Contents
問題
開発しているReact + TypeScriptのWebアプリケーションを、デバッグのためにローカルサーバで起動したときに、アプリからAPI Management上に登録したAPIを呼び出すとCORSエラーが発生してしまいました。これを正常に実行できるようにする必要がありました。
CORSエラーが発生しているかどうかは、ブラウザの開発者ツールから確認できます。
さらに、Consoleタブから、エラーの詳細を確認できます。
Access to fetch at 'APIのURL' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
以下のMozilaのページに記載があったのですが、CORSエラーはセキュリティの観点からブラウザのコンソールからしか確認できないみたいようです。
CORSとは?
CORSについてはこちらの記事にまとめたので、よろしければご参照ください。
問題の解消方法
エラー内容を改めてみると、preflight requestのレスポンスヘッダにAccess-Control-Allow-Originヘッダがないよ、と怒られています。
これはAPI Management側でCORSを実現するための設定が不足しているために発生しています。
API Management側では、以下ドキュメントの通りCORSを利用する場合追加の設定が必要ですので、こちらに沿って設定を進めていきます。
https://docs.microsoft.com/ja-jp/azure/api-management/api-management-cross-domain-policies
以下の通り、API ManagemtnのInbound processingのルールを編集します。
以下のように、<cors>から始まるセクションを追加します。
ここで1点注意なのは、<base />よりも前に入れる、ということです。API managementのこれらのpolicyは、上から順に評価されます。理由はよく理解できていませんが、<base/>を先に入れてしまうと、CORSエラーが発生したままになってしまいました。
・・・・
<inbound>
<rewrite-uri template="XXXX" />
<set-backend-service id="apim-generated-policy" backend-id="XXXXX" />
<cors>
<allowed-origins>
<origin>http://localhost:3000</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>*</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
</cors>
<base />
</inbound>
・・・・
これだけでOK。
Preflightも正式なfetch (POST)リクエストも成功するようになりました。
以上、最後まで読んでいただきありがとうございました。
本記事がお役に立ちましたら、下のいいねをポチッていただけますと励みになります!
それでは!