LoginSignup
2
1

More than 1 year has passed since last update.

create-react-appプロジェクトの開発中にSpring Bootへプロキシさせる

Posted at

開発中のcreate-react-appで作成したプロジェクトから、Spring Bootアプリケーションへプロキシさせる設定で躓いたので、ここに記します。
create-react-appのバージョンは5.0.1、Spring Bootは2.7.3です。

proxyオブションで済むなら問題なし

Proxying API Requests in Developmentを参考に

package.json
"proxy": "http://localhost:8080"

を追加するだけで

のような連係が可能になります。簡単ですねぇ

ただ注意が必要なのが、プロキシされるのはブラウザからのリクエストのAcceptヘッダにtext/htmlが無い場合だけです。

プロキシの手動設定で問題発生

例えば自分の場合は、ファイルダウンロード処理が必要となり、proxyオブションを諦める必要がありました。
そこでドキュメントを参考に

src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:8080',
      changeOrigin: true,
    })
  );
  app.use(
    '/resource',
    createProxyMiddleware({
      target: 'http://localhost:8080',
      changeOrigin: true,
    })
  );
};

としたところ、Spring Bootへ通信が全て 403 Forbidden になってしまいました。レスポンスのボディ部には「Invalid CORS request」の文字があります。

原因

proxyオブションの場合と、手動設定の場合でSpring Boot側の動きの違いを確認すると、CorsFilterから呼び出された

org.springframework.web.cors.DefaultCorsProcessor.java
public class DefaultCorsProcessor implements CorsProcessor {
	public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request,
			HttpServletResponse response) throws IOException {

         省略 
		if (!CorsUtils.isCorsRequest(request)) {
			return true;
		}

CorsUtils.isCorsRequestメソッドで、前者はfalseでCross Originではないと判定され、後者はCross Originと判定されてました。
CorsUtils.isCorsRequestメソッドの内部ではhostヘッダとoriginヘッダのスキーマ、ホスト名、ポート番号の何れかが異なるとCross Originと判定されます。

各設定でSpring Bootが受信している値が以下になります。

hostヘッダ originヘッダ
proxyオブション localhost:8080 http://localhost:8080
手動設定(changeOrigin: true) localhost:8080 http://localhost:3000
手動設定(changeOrigin: false) localhost:3000 http://localhost:3000
  • hostヘッダにないスキーマは、HttpServletRequest.getScheme()より取得。この値は、Tomcatの場合、受信したコネクタで決まる。

つまり、

ということで、CORS問題を回避しているつもりでtrueにしたら、逆にCORS問題に躓いたみたいです、、、orz

対処

本来はCORSの設定を怠らないべきなんでしょうが、開発中というこで、changeOrigin: trueにしたまま、Spring Boot側のCORSチェックを無効化する道を選びました。

GraphQL Java KickstartのGraphQL Spring Bootを使用しているなら以下の設定です。

application.yml
graphql:
  servlet:
    cors-enabled: false
2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1