0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Golang(Gin)のRouteファイルに記載するCORS設定で起きたエラー

Posted at

はじめに

Gin + Next.jsの勉強をしていてCORSの設定をしていたのですが、何度もCORSエラーが生じて解決するのに1日以上費やしてしまったので、その備忘録として今回の投稿を作成します。

CORSとは

CORSとは簡単に言うと、

悪意のあるウェブサイトが明示的な権限を持たずに他のサイトのデータ (Box APIなど) にアクセスするのを防ぐために、ウェブブラウザで利用されているセキュリティメカニズム

のことです。

問題のソースコード

修正前

package router

import (
	"gin-twitter/controllers"
	"net/http"
	"os"

	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	csrf "github.com/utrack/gin-csrf"
)

func NewRouter(uc controllers.IUserController) *gin.Engine {
	r := gin.Default()

	api := r.Group("/api")
	api.Use(gin.Logger())

    // CORS
    r.Use(cors.New(cors.Config{
		AllowOrigins: []string{
			os.Getenv("FE_URL"),
		},
		AllowHeaders: []string{
			"Origin",
			"Content-Type",
			"Accept",
			"Access-Control-Allow-Headers",
			"X-CSRF-Token",
			"Access-Control-Allow-Origin",
		},
		AllowMethods: []string{
			"GET",
			"POST",
			"PUT",
			"DELETE",
			"OPTIONS",
		},
		AllowCredentials: true,
	}))

	api.Use(sessions.Sessions("mysession", cookie.NewStore([]byte("secret"))))
	// CSRF
	api.Use(csrf.Middleware(csrf.Options{
		// Secret: CSRFトークンの署名に使用するシークレットを設定します。ランダムな強力な文字列を設定してください。
		Secret: os.Getenv("SECRET"),
		// IgnoreMethods: CSRFトークンを検証しないHTTPメソッドを指定できます。
		IgnoreMethods: []string{"GET"},
		// ErrorFunc: CSRFトークンが一致しない場合に実行されるハンドラを指定できます。
		ErrorFunc: func(c *gin.Context) {
			c.JSON(http.StatusForbidden, gin.H{"error": "CSRF token mismatch"})
			c.Abort()
		},
		// TokenGetter: リクエストからCSRFトークンを取得するカスタム関数です。
		TokenGetter: func(c *gin.Context) string {
			return c.GetHeader("X-CSRF-TOKEN")
		},
	}))

	api.POST("/signup", uc.SignUp)
	api.POST("/login", uc.LogIn)
	api.GET("/csrf", uc.CsrfToken)

	return r
}

修正後

package router

import (
	"gin-twitter/controllers"
	"net/http"
	"os"

	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	csrf "github.com/utrack/gin-csrf"
)

func NewRouter(uc controllers.IUserController) *gin.Engine {
	r := gin.Default()

	r.Use(cors.New(cors.Config{
		AllowOrigins: []string{
			os.Getenv("FE_URL"),
		},
		AllowHeaders: []string{
			"Origin",
			"Content-Type",
			"Accept",
			"Access-Control-Allow-Headers",
			"X-CSRF-Token",
			"Access-Control-Allow-Origin",
		},
		AllowMethods: []string{
			"GET",
			"POST",
			"PUT",
			"DELETE",
			"OPTIONS",
		},
		AllowCredentials: true,
	}))

	api := r.Group("/api")
	api.Use(gin.Logger())

	// CORS

	api.Use(sessions.Sessions("mysession", cookie.NewStore([]byte("secret"))))
	// CSRF
	api.Use(csrf.Middleware(csrf.Options{
		// Secret: CSRFトークンの署名に使用するシークレットを設定します。ランダムな強力な文字列を設定してください。
		Secret: os.Getenv("SECRET"),
		// IgnoreMethods: CSRFトークンを検証しないHTTPメソッドを指定できます。
		IgnoreMethods: []string{"GET"},
		// ErrorFunc: CSRFトークンが一致しない場合に実行されるハンドラを指定できます。
		ErrorFunc: func(c *gin.Context) {
			c.JSON(http.StatusForbidden, gin.H{"error": "CSRF token mismatch"})
			c.Abort()
		},
		// TokenGetter: リクエストからCSRFトークンを取得するカスタム関数です。
		TokenGetter: func(c *gin.Context) string {
			return c.GetHeader("X-CSRF-TOKEN")
		},
	}))

	api.POST("/signup", uc.SignUp)
	api.POST("/login", uc.LogIn)
	api.GET("/csrf", uc.CsrfToken)

	return r
}

api := r.Group("/api")を先に記述し、その後にCORSの設定を入れていたことが問題でした。
先にCORSの設定をし、その後でルーティングの設定を行うことでエラーは解消されました。

最後に

ルーティングの順番には注意しましょう。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?