カテゴリ: Spring認証(Spring Security) 更新日: 2025/12/28

CORSリクエストヘッダーの基本を解説!Originヘッダーの仕組みと使い方

CORSのリクエストヘッダーとレスポンスヘッダー
CORSのリクエストヘッダーとレスポンスヘッダー

新人と先輩の会話形式で理解しよう

新人

「先輩、Javaの開発で別のドメインにAPIリクエストを送ろうとしたら、CORSエラーって出たんですけど、CORSってなんですか?」

先輩

「それはCORS(Cross-Origin Resource Sharing)っていうセキュリティ機能が原因だね。Webブラウザが、異なるオリジン間でのリソース共有を制限してるんだ。」

新人

「オリジンって、何を指してるんですか?」

先輩

「オリジンは、スキーム(http/https)・ドメイン・ポート番号の組み合わせを指すんだよ。たとえば、http://localhost:8080からhttp://api.example.comにアクセスするのはクロスオリジンになるんだ。」

新人

「なるほど!じゃあ、CORSで使われるリクエストヘッダーには何があるんですか?」

先輩

「よし、それじゃ今回はCORSリクエストヘッダーの仕組みと、よく使われるOriginヘッダーやAccess-Control-Request-Methodについて詳しく説明するよ。」

1. CORSとは?基本のおさらい

1. CORSとは?基本のおさらい
1. CORSとは?基本のおさらい

CORS(コース:Cross-Origin Resource Sharing)とは、異なるオリジン間でのHTTPリクエストを安全に行うための仕組みです。たとえば、http://localhost:3000のフロントエンドから、http://api.example.comのバックエンドへ通信を行う場合、これは「クロスオリジン通信」と呼ばれます。

通常、ブラウザはこのようなクロスオリジン通信をブロックします。しかし、CORSを正しく設定すれば、安全な通信が可能になります。CORSの仕組みでは、リクエストヘッダーレスポンスヘッダーを使って、どのオリジンからの通信を許可するかを制御します。

つまり、クライアントが送る「CORSリクエストヘッダー」と、サーバーが返す「CORSレスポンスヘッダー」の組み合わせによって、通信の可否が決定されるのです。

2. CORSリクエストヘッダーとは?役割と代表例

2. CORSリクエストヘッダーとは?役割と代表例
2. CORSリクエストヘッダーとは?役割と代表例

CORSのリクエスト時に、ブラウザは自動的にいくつかのHTTPヘッダーを追加します。これが「CORSリクエストヘッダー」と呼ばれるものです。これらのヘッダーによって、ブラウザはサーバーに「この通信はクロスオリジンです」と伝え、アクセスの許可を求めます。

2-1. Originヘッダー

もっとも基本的なCORSリクエストヘッダーがOriginヘッダーです。これはリクエスト元のスキーム・ドメイン・ポートを示し、サーバーに対して「このオリジンからの通信を許可してほしい」と伝える役割を持ちます。

たとえば、以下のようなHTTPリクエストが送られます。


GET /api/data HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000

この例では、クライアントがhttp://localhost:3000で、サーバーはhttp://api.example.comとなっており、異なるオリジン間での通信になっています。

2-2. Access-Control-Request-Methodヘッダー

Access-Control-Request-Methodは、プリフライトリクエスト(事前確認リクエスト)で使用されるヘッダーです。これは、実際の通信を行う前に、ブラウザがサーバーに対して「このメソッドでアクセスしたいけど許可してくれる?」と問い合わせるために使います。

たとえば、以下のようなOPTIONSリクエストが送られます。


OPTIONS /api/user HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000
Access-Control-Request-Method: POST

このプリフライトリクエストに対して、サーバーがCORSレスポンスヘッダーで許可すれば、本リクエスト(POSTリクエスト)が実行されます。

2-3. Access-Control-Request-Headersヘッダー

このヘッダーは、プリフライトリクエストでクライアントが使用予定のカスタムヘッダーをサーバーに通知するために使います。

たとえば、次のようなヘッダーです。


OPTIONS /api/user HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

このようにして、クライアントが独自のヘッダー(例:X-Custom-Header)を使う場合にも、事前にサーバーへ通知する必要があるのです。

2-4. Javaでの確認方法(@Controllerを使用)

Spring Bootを使用している場合、@Controllerを使って受け取ったCORSリクエストを確認できます。以下のように記述すれば、リクエストヘッダーをログ出力できます。


@Controller
public class CorsExampleController {

    @RequestMapping("/api/data")
    @ResponseBody
    public String getData(HttpServletRequest request) {
        String origin = request.getHeader("Origin");
        System.out.println("Originヘッダーの値: " + origin);
        return "CORSリクエストを受け付けました";
    }
}

このようにして、Originヘッダーなどの内容を確認しながらCORS通信を理解することができます。

3. CORSレスポンスヘッダーの意味と必要性

3. CORSレスポンスヘッダーの意味と必要性
3. CORSレスポンスヘッダーの意味と必要性

サーバー側では、クライアントから送られたCORSリクエストヘッダーに対して、対応する「CORSレスポンスヘッダー」を返す必要があります。このレスポンスヘッダーがないと、ブラウザはセキュリティ上の理由からレスポンスをブロックしてしまいます。つまり、CORS通信を許可するには、サーバー側で明示的に許可を示すレスポンスヘッダーを設定する必要があります。

3-1. Access-Control-Allow-Originとは

Access-Control-Allow-Originは、もっとも重要なCORSレスポンスヘッダーのひとつです。このヘッダーは「どのオリジンからのリクエストを許可するか」を指定します。

たとえば、次のように設定すると、http://localhost:3000というオリジンからのアクセスだけが許可されます。


Access-Control-Allow-Origin: http://localhost:3000

すべてのオリジンを許可したい場合は、アスタリスク(*)を使うこともできます。ただし、あとで解説する認証情報(クッキーなど)を使う場合は、*は使えません。

3-2. Access-Control-Allow-Methods

Access-Control-Allow-Methodsは、クライアントが使用できるHTTPメソッド(GET、POSTなど)を指定するレスポンスヘッダーです。


Access-Control-Allow-Methods: GET, POST, PUT, DELETE

このヘッダーが正しく設定されていないと、プリフライトリクエストでエラーになります。

3-3. Access-Control-Allow-Headers

Access-Control-Allow-Headersは、クライアントがリクエスト時に使用するカスタムヘッダーを許可するためのレスポンスヘッダーです。


Access-Control-Allow-Headers: Content-Type, X-Custom-Header

この指定がなければ、X-Custom-Headerなどのカスタムヘッダーはブロックされます。

3-4. Access-Control-Allow-Credentials

Access-Control-Allow-Credentialsは、クライアントがクッキーや認証トークンなどの「認証情報」をサーバーに送ることを許可するために使うレスポンスヘッダーです。


Access-Control-Allow-Credentials: true

このヘッダーを使う場合、Access-Control-Allow-Origin*を設定することはできません。後述するように、設定ミスの原因にもなります。

4. Spring SecurityでCORSレスポンスヘッダーを設定する方法

4. Spring SecurityでCORSレスポンスヘッダーを設定する方法
4. Spring SecurityでCORSレスポンスヘッダーを設定する方法

Spring Securityを使用している場合、CORSのレスポンスヘッダーはWebSecurityConfigurerAdapterを拡張して設定します。以下にGradle構成のSpring Bootプロジェクトにおける基本的なCORS設定の例を示します。


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors() // CORSを有効にする
            .and()
            .csrf().disable(); // 開発環境ではCSRFを無効化
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        config.setAllowCredentials(true); // 認証情報を許可

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

この設定では、http://localhost:3000からのリクエストを許可し、すべてのHTTPメソッドとヘッダーを許可しています。また、setAllowCredentials(true)を設定することで、認証情報の送信も可能になります。

5. よくあるCORSレスポンスの設定ミスと対策

5. よくあるCORSレスポンスの設定ミスと対策
5. よくあるCORSレスポンスの設定ミスと対策

ここでは初心者が陥りやすいCORS設定のミスと、その対処方法を解説します。

5-1. 「*」と認証情報の併用によるエラー

Access-Control-Allow-Origin*に設定しながら、Access-Control-Allow-Credentials: trueを指定してしまうケースは非常に多いですが、これは明確な仕様違反です。ブラウザはこの組み合わせを拒否し、CORSエラーになります。

対策としては、オリジンを明示的に指定するようにします。


config.addAllowedOrigin("http://localhost:3000"); // * ではなく明示的に
config.setAllowCredentials(true);

5-2. OPTIONSリクエストが拒否される

ブラウザがプリフライト(OPTIONS)リクエストを送っても、サーバーがそのリクエストに対応していない場合、CORS通信は失敗します。

Spring Bootでは、以下のようにコントローラでOPTIONSリクエストを明示的に許可しておくと安心です。


@Controller
public class CorsOptionsController {

    @RequestMapping(value = "/api/**", method = RequestMethod.OPTIONS)
    @ResponseBody
    public ResponseEntity<?> handleOptions() {
        return ResponseEntity.ok().build();
    }
}

5-3. フロントエンドとの通信テストでCORSエラー

開発初期にありがちなミスとして、フロントエンド側とバックエンド側のポート番号が異なることでCORS通信になっていることに気づかず、CORS設定を忘れてしまうことがあります。

たとえば、http://localhost:3000http://localhost:8080は別オリジンとして扱われるため、CORS対応が必要です。通信ができないときは、まずはオリジンの違いを確認することが大切です。

6. 実際のリクエストとレスポンスのHTTPヘッダー表示例

6. 実際のリクエストとレスポンスのHTTPヘッダー表示例
6. 実際のリクエストとレスポンスのHTTPヘッダー表示例

CORS通信の際に発生するHTTPヘッダーは、ブラウザの開発者ツールで簡単に確認できます。たとえば、Google Chromeであれば、右クリックから「検証」→「Network」タブを開き、対象のリクエストをクリックすることで「Headers」タブに詳細が表示されます。

ここでは、フロントエンドからバックエンドへPOSTリクエストを送信した場合のリクエストとレスポンスのCORS HTTPヘッダー例を紹介します。

6-1. リクエスト時のHTTPヘッダー(例)


POST /api/login HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000
Content-Type: application/json
Referer: http://localhost:3000/login

このように、Originヘッダーがhttp://localhost:3000であることにより、クロスオリジン通信であると判断されます。

6-2. レスポンス時のHTTPヘッダー(例)


HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true
Content-Type: application/json

ここで重要なのはAccess-Control-Allow-Originが明示的に指定されている点です。また、クッキーなどの認証情報を扱う場合はAccess-Control-Allow-Credentials: trueも必須になります。

7. セキュリティの観点でのベストプラクティス

7. セキュリティの観点でのベストプラクティス
7. セキュリティの観点でのベストプラクティス

CORSの設定は柔軟であるがゆえに、セキュリティリスクも伴います。特に本番環境でのCORS設定には注意が必要です。ここでは「CORS セキュリティベストプラクティス」として、よく守られるべき設定方針を紹介します。

7-1. 不要なオリジンを許可しない

Access-Control-Allow-Origin*を指定すると、すべてのオリジンからのアクセスを許可してしまうため、非常に危険です。特に機密情報や認証機能を伴うエンドポイントでは、必ず信頼できるオリジンを明示的に指定しましょう。


config.addAllowedOrigin("https://trusted.example.com");

7-2. 認証情報の扱いに注意

クッキーやセッショントークンなどの認証情報をCORS通信で扱う場合、Access-Control-Allow-Credentialsの設定が必要です。同時に、オリジンの制限もセットで行わないと、第三者による不正アクセスが可能になるリスクがあります。

セッションを使う場合は、SameSite=NoneかつSecure属性をクッキーに付与することも忘れてはいけません。

7-3. 本番環境と開発環境の設定を分離する

開発中は利便性を重視してCORSを広く許可することがありますが、本番環境では必ずオリジンを制限しましょう。Springではプロファイル(例:dev、prod)を分けてCORS設定を切り替えることができます。


@Profile("dev")
@Bean
public CorsConfigurationSource devCorsConfig() {
    CorsConfiguration config = new CorsConfiguration();
    config.addAllowedOrigin("*");
    config.addAllowedMethod("*");
    return source;
}

8. CORSヘッダーの設定ミスが引き起こすリスクとトラブルシューティング

8. CORSヘッダーの設定ミスが引き起こすリスクとトラブルシューティング
8. CORSヘッダーの設定ミスが引き起こすリスクとトラブルシューティング

CORSの設定を誤ると、正しく動作しないだけでなく、セキュリティホールを作ることにもなります。ここでは「CORS トラブルシューティング」の観点でよくあるミスとその解決方法を紹介します。

8-1. 設定は正しいのにCORSエラーが出る

レスポンスに必要なヘッダーが正しく返っていないときに発生することがあります。特に、OPTIONSメソッドへの対応漏れが原因のことが多いため、@RequestMapping(method = RequestMethod.OPTIONS)があるかを確認してください。

8-2. フロントエンド側の設定不備

JavaScript側でfetchaxiosを使う際に、credentials: 'include'を指定していないと、クッキーが送信されません。バックエンドがAccess-Control-Allow-Credentialsを返していても、クライアント側の指定がなければ意味がありません。

8-3. ブラウザのキャッシュが悪さをする

一度CORSエラーが出ると、ブラウザがキャッシュした情報のせいで、設定変更後も同じエラーが続く場合があります。念のためブラウザのキャッシュをクリアしたり、シークレットモードで再確認するとよいでしょう。

8-4. Spring Securityの順序が影響している

Spring SecurityでCORSの設定よりも先にセキュリティ制限が働いてしまうと、CORSレスポンスヘッダーが返らないケースがあります。http.cors()の順序やFilterRegistrationBeanの設定順に注意してください。

まとめ

まとめ
まとめ

この記事では、CORSリクエストヘッダーとレスポンスヘッダーの仕組みを中心に、CORSとは何かOriginヘッダーの役割プリフライトリクエスト(OPTIONS)、そしてSpring Boot・Spring Securityでの具体的な設定方法までを丁寧に解説してきました。

CORSは一見すると難しく感じやすい仕組みですが、基本に立ち返ると「ブラウザが異なるオリジン間の通信を安全に管理するためのルール」であることが分かります。 特に重要なのは、クライアントが送るCORSリクエストヘッダーと、サーバーが返すCORSレスポンスヘッダーがセットで機能している点です。

Originヘッダーは「どこから来たリクエストか」を示し、Access-Control-Request-Method や Access-Control-Request-Headers は「これから何をしたいか」を事前に伝えます。 それに対してサーバー側は、Access-Control-Allow-Origin や Access-Control-Allow-Methods などを使って「どこまで許可するか」を明確に示します。 このやり取りの合意が取れなければ、ブラウザは通信をブロックします。

また、Access-Control-Allow-Credentials と Access-Control-Allow-Origin の組み合わせや、OPTIONSリクエストの扱いなど、設定ミスが起きやすいポイントも多く存在します。 CORSエラーが出たときは、コードだけを見るのではなく、「どのオリジンから」「どのヘッダーが」「どの順序で」送られているのかを落ち着いて確認することが重要です。

CORS理解を助ける確認用サンプルコード

最後に、CORSの理解を深めるためのシンプルな確認用サンプルをもう一度整理しておきましょう。 以下は、ブラウザから送られる代表的なCORSリクエストヘッダーの例です。


GET /api/data HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000

このリクエストに対して、サーバーが次のようなレスポンスヘッダーを返せば、ブラウザは通信を許可します。


HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true

この「OriginとAllow-Originの一致関係」を確認するだけでも、多くのCORSエラーは原因が見えてきます。

先生と生徒の振り返り会話

生徒

「最初はCORSエラーが出るたびに、何が起きているのか全然分からなかったんですが、 Originヘッダーとレスポンスヘッダーの関係を意識すると、少しずつ見えてきました。」

先生

「それが一番大事なポイントだね。CORSは“魔法の設定”じゃなくて、 ブラウザとサーバーの間の確認ルールにすぎないんだ。」

生徒

「特に、Access-Control-Allow-Origin に * を使えばいいと思っていたのが間違いだと分かりました。 認証情報があると使えないんですね。」

先生

「そう。便利そうに見える設定ほど、実は制限があることが多い。 だからこそ、CORSは“なぜその設定が必要なのか”を理解しながら使うことが重要なんだ。」

生徒

「これからCORSエラーが出ても、慌てずにリクエストヘッダーとレスポンスヘッダーを確認してみます。」

先生

「それで大丈夫。CORSを理解できたということは、Webの仕組みを一段深く理解できた証拠だよ。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

CORSとは何ですか?なぜ必要なのですか?

CORS(Cross-Origin Resource Sharing)は、異なるオリジン(ドメインやポート)が通信する際に、セキュリティを確保するためのブラウザの仕組みです。クロスオリジン通信を許可するには、サーバー側が明示的に設定する必要があります。
コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
Spring認証(Spring Security)
Spring BootでCORSを設定する方法を完全解説!初心者でもわかるセキュリティ対策
New2
Spring認証(Spring Security)
パスワードをハッシュ化する理由とは?セキュリティ対策の基本をSpring Securityで学ぼう
New3
SpringのWeb開発(Spring MVC)
HTTPリクエストとレスポンスの基本を完全解説!Spring MVC初心者がWeb通信の仕組みをやさしく理解
New4
Spring認証(Spring Security)
ブラウザからのフォーム送信とは?HTTPリクエストの基礎を初心者向けに解説!
人気記事
No.1
Java&Spring記事人気No1
SpringのWeb開発(Spring MVC)
ルーティングとは?基本概念(Spring MVCのURL制御を理解)
No.2
Java&Spring記事人気No2
Thymeleaf
Thymeleaf とは?初心者向けにThymeleafの基本を徹底解説
No.3
Java&Spring記事人気No3
Springの基本
application.properties と YAML の基本をやさしく解説!初心者向けSpring Boot設定ファイル入門
No.4
Java&Spring記事人気No4
Springの基本
Spring Bootのデフォルトログ設定を徹底解説(Logback / SLF4J)
No.5
Java&Spring記事人気No5
Springの基本
Spring Bootの環境変数の設定方法をやさしく解説!初心者向けapplication.propertiesの使い方
No.6
Java&Spring記事人気No6
SpringのWeb開発(Spring MVC)
ループ処理(th:each)の基本を完全ガイド!Thymeafの繰り返し処理の使い方
No.7
Java&Spring記事人気No7
SpringのDB操作
JPAの標準クエリメソッド(findById, findAll)を完全解説!初心者でもわかるデータ取得の基本
No.8
Java&Spring記事人気No8
Spring認証(Spring Security)
セッション管理の基本(@SessionAttributes)を完全解説!初心者でもわかるセッションの仕組み