cors icon indicating copy to clipboard operation
cors copied to clipboard

GIN: cannot use CORS middleware with router groups

Open samber opened this issue 5 years ago • 5 comments

I need different CORS settings in 2 groups. This middleware works only at "router" level.

The issue can be reproduced with the following code:

package main

import (
	cors "github.com/rs/cors/wrapper/gin"
	"github.com/gin-gonic/gin"
)

func ctrl(c *gin.Context) {
	c.JSON(200, gin.H{
		"status": "ok",
	})
}

func main() {
	router := gin.New()

	// first group with "/1" prefix
	group1 := router.Group("/1")
	group1.Use(cors.New(cors.Options{
		AllowedOrigins:   []string{"http://a.b.c"},
		AllowedMethods:   []string{"GET", "HEAD", "OPTIONS",},
		AllowedHeaders:   []string{"Origin", "Content-Type"},
		AllowCredentials: false,
	}))
	group1.GET("/1", ctrl)

	// second group with "/2" prefix
	group2 := router.Group("/2")
	group2.Use(cors.New(cors.Options{
		AllowedOrigins:   []string{"http://d.e.f"},
		AllowedMethods:   []string{"GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH", "DELETE"},
		AllowedHeaders:   []string{"Origin", "Authorization", "Cookie", "Content-Type"},
	}))
	group2.GET("/2", ctrl)

	router.Run(":8080")
}

Adding the "OPTIONS" catch-all route doesn't change anything.

group1.OPTIONS("", func(c *gin.Context) {
	c.AbortWithStatus(204)
})

You can test it with this client.

Any idea how to solve this?

samber avatar Jun 21 '20 16:06 samber

Any luck @samber ?

sno6 avatar Sep 03 '20 09:09 sno6

@samber I am also facing the same issue.

mjubil1 avatar Sep 13 '20 00:09 mjubil1

I think cors runs first, when the connection is established, and does not know anything about the endpoint itself ("1/*") so it cannot be used at the Group granularity level.

RubenGarcia avatar Jul 30 '21 09:07 RubenGarcia

I had to add an options mapping to each endpoint

sify21 avatar Dec 04 '21 01:12 sify21

web browser will send OPTIONS to check CORS policy before request. In common secranio. router only define specific method like get, post. SO when server recieve options method. It will reconginze this route is not registed. then code run into default middleware

// Use attaches a global middleware to the router. ie. the middleware attached though Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware.
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
	engine.RouterGroup.Use(middleware...)
	engine.rebuild404Handlers()
	engine.rebuild405Handlers()
	return engine
}

use cors middlware in default group!!!

OhBonsai avatar Jan 04 '22 09:01 OhBonsai