Tagbangers Blog

Spring Cloud Gateway の CORS 設定を Vercel の自動生成 URL に対応させる

下記の環境に対応させるために 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 を自動生成します

Generated URLs – Vercel Docs

<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 の再起動では反映されるため、同じ環境で試しているかたは注意した方が良さそうです