下記の環境に対応させるために Spring Cloud Gateway の設定の調整をした時のメモです
- フロントエンドアプリケーションは Vercel にデプロイ
- API サーバの前段に CORS が有効な Gateway サーバがいる
- フロントエンドアプリケーションと Gateway サーバのドメインが異なる
CORS の設定は application.yml
で指定することが可能です
Spring Cloud Gateway のドキュメントとしてはサンプルとして下記の書き方が紹介されています
CORS Configuration - Spring Cloud Gateway
spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "https://docs.spring.io" allowedMethods: - GET
allowedOrigins
は配列で指定することで複数指定可能ですが正規表現で指定することはできず、全許可用の *
か固定ドメインの指定かのいづれかのみです
Vercel はプロジェクト生成時およびブランチ・コミットごとに下記の規則で URL を自動生成します
<project-name>-<unique-hash>-<scope-slug>.vercel.app
この自動生成 URL に対応するためには柔軟な指定をする必要があり Spring のコードを調査していましたが、allowedOriginPatterns
という設定項目があることを発見しました
CorsConfiguration (Spring Framework API) - Javadoc)
ポートリストに加えて、ホスト名の任意の場所に
*
が付いた、より柔軟なオリジンパターンをサポートするsetAllowedOrigins(java.util.List<java.lang.String>)
の代替。例: https://*.domain1.com-domain1.com で終わるドメイン ...
注: Spring Framework 5.3 から追加された機能のため Spring Boot 2.4 より低いプロジェクトでは利用できません
こちらを利用し下記のように指定することで Vercel の自動生成 URL を許可することができました
例)組織 ID my-organization
プロジェクト my-project
spring:
cloud:
gateway:
globalcors:
cors-configurations:
"[/**]":
allowedOriginPatterns:
# Vercel プロジェクト作成時のデフォルトの Production URL
- "https://my-project
.vercel.app"
# Vercel 自動生成 Preview URL
- "https://my-project-*-my-organization.vercel.app"
Vercel 以外にもある程度柔軟性のある CORS の設定を行いたい場合に利用できます
余談
今回の調査を行っていた環境では Gateway サーバは Spring Cloud Kubernetes を導入しており Kubernetes 上にデプロイされている状態でした
application.yml
の設定は Kubernetes の ConfigMap で管理しており、Spring Cloud Kubernetes の機能によりアプリケーションが自動的に設定をリロードする想定だったのですが
PropertySource
Reload - Spring Cloud Kubernetes
spring.cloud.gateway.globalcors
を設定した場合のみアプリのリフレッシュログは出るものの設定が反映されてない状態でした
Pod の再起動では反映されるため、同じ環境で試しているかたは注意した方が良さそうです