Gin echo corsのオリジンをHttp Request から取得する
今回は Go のwebフレームワーク Gin, echo でCORSの設定を行う時にhttp Request からoriginを取得してHeaderに付与する方法を見ていきます。
発端はvercelのプレビュー環境(ランダムなURL)でもクライアントからAPIを叩けるようにする為でした。
*cookieを送信するようにするため、access-control-allow-credentialsをtrueにした場合、allow-originにはワイルドカードを使うことができません。
また、GinやechoのフレームワークはCORSをいい感じに設定してくれるメソッドを提供していますが、そちらを使用した場合あらかじめoriginを設定する必要がありました。どのようにカスタマイズするかも合わせて見ていきます。
なお、今回はCORS自体の説明はしないので復習したい方はこちらの記事がおすすめです。
ソースコード
Ginの場合
カスタム前
func NewCors() gin.HandlerFunc { return cors.New(cors.Config{ AllowOrigins:[]string{"http://localhost:3000", "http://localhost:3001"}, AllowMethods: []string{"GET", "POST"}, AllowHeaders: []string{ "Origin", "Content-Length", "Content-Type", "Authorization", }, AllowCredentials: true, MaxAge: 12 * time.Hour, }) }
カスタム後
func NewCors() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", c.Request.Header.Get("Origin")) c.Writer.Header().Set("Access-Control-Max-Age", "12h0m0s") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET") c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Authorization") c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") if c.Request.Method == http.MethodOptions { c.AbortWithStatus(204) return } c.Next() } }
echoの場合
カスタム前
func NewCors() echo.MiddlewareFunc { return middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins:[]string{"http://localhost:3000", "http://localhost:3001"}, AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept}, AllowCredentials: true, MaxAge: 43200, }) }
カスタム後
func NewCors() echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { c.Response().Writer.Header().Set("Access-Control-Allow-Origin", c.Request().Header.Get("Origin")) c.Response().Header().Set("Access-Control-Max-Age", "12h0m0s") c.Response().Header().Set("Access-Control-Allow-Methods", "POST, GET") c.Response().Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Authorization") c.Response().Header().Set("Access-Control-Expose-Headers", "Content-Length") c.Response().Header().Set("Access-Control-Allow-Credentials", "true") if c.Request().Method == http.MethodOptions { return c.NoContent(http.StatusNoContent) } return next(c) } } }
いずれも以下のコードでhttp.Headerからoriginを取得しています。
c.Request().Header.Get("Origin")
ヘッダーを付与した後は プリフライトリクエストの"OPTION"メソッドで204を返すようにしています。
これでどのoriginからでもAPIを叩くことができますね!
Ginやechoはwebフレームワークとしては軽量なのでカスタマイズがしやすいと思います。 その分net/http など標準パッケージの理解を深める事が大事だと思いました。
内容は以上となります。
最後に、 このブログではweb開発について発信していくのでまたご覧頂けると嬉しいです。 最後までお読み頂きありがとうございました。
参考記事