🔖

Go言語でCORSを実装してみよう!

2025/02/17に公開

バックエンドをGo言語、フロントエンドをReactでアプリを作っています。
フロントからフォームを送信するとき、CORSが必要だったのでやり方をメモしておきます。

3つの手順で進行していきます。

  1. CORSで失敗したいこと
  2. CORSの2つの書き方
  3. CORSはどっちを使うと良いのか?

ディレクトリ構成

今回必要そうな部分だけ抜粋しました。

.
├── backend/
│   ├── middlewares/
│   │   └── cors.go ## CORSの設定を記述
│   └── main.go ### CORSの設定を呼び出し
├── frontend/
│   ├── src/
│   │   └── components/
│   │       └── UserForm.tsx ## ここにフォームを記述
│   ├── App.tsx
│   └── main.tsx
└── docker-compose.yml

CORSを2つ紹介

まず、できなかったCORSから紹介します。

import github.con/gin-gonic/contrib/cors
AllowedHeaders: []string{"GET", },

この記述は、Gin公式の旧版ライブラリ集 (contrib)のためうまくいきませんでした。

使用できた1つ目のCORS

package middlewares

import (
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

// CORSミドルウェアの設定
func SetupCORS(r *gin.Engine) {
	r.Use(cors.New(cors.Config{
		// React アプリのホストURLを指定
		AllowOrigins:     []string{"http://localhost:5173"},
		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowHeaders:     []string{"Origin", "Content-Type", "Authorization"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		MaxAge:           12 * time.Hour,
	}))
}

こちらの記述は使えました。

// main.go
func main() {
    r := gin.Default()
	// CORS設定
	middlewares.SetupCORS(r)
}

上記の記述で使えるようになりました。
キャッシュが残っている可能性もあるので、
スーパーリロードしてから再度POSTしてみてください。

使用できた2つ目のCORS

package middlewares

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

		// プリフライトリクエスト (OPTIONS) への即時レスポンス
		if c.Request.Method == http.MethodOptions {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	}
}
    // main.go
    // Gin ルーターを作成
	r := gin.Default()
	// CORSミドルウェアを有効化
	r.Use(middlewares.CORSMiddleware())

どっちのCORSが良いのか?

1つ目のCORSの方が安全で高速みたいです。

"github.com/gin-gonic/gin"
MaxAge: 12 * time.Hour, // プリフライト結果を12時間キャッシュ

この記述は、Reactアプリが頻繁にAPIを呼ぶ際の
パフォーマンスが大幅に向上するみたいなのでいいらしいですね。

書き方もわかりやすいので、1つ目がいいんじゃないかと思いました。

Discussion