Coder Social home page Coder Social logo

cors's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cors's Issues

Unable to run example with latest Gin

When I import the following.

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

Then I try use the example:

	router := gin.New()

	router.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"https://foo.com"},
		AllowMethods:     []string{"PUT", "PATCH"},
		AllowHeaders:     []string{"Origin"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		AllowOriginFunc: func(origin string) bool {
			return origin == "https://github.com"
		},
		MaxAge: 12 * time.Hour,
	}))

I get the following error:

cannot use cors.New(cors.Config literal) (type "github.com/gin-gonic/gin".HandlerFunc) as type "mend/vendor/github.com/gin-gonic/gin".HandlerFunc in argument to router.Use

Problem with AllowAllOrigins

Following code is my configuration for enabling CORS needed for cookie-based authentication:

     r.Use(cors.New(cors.Config{
                AllowAllOrigins:  true,
                AllowMethods:     []string{"GET", "POST", "PUT", "HEAD"},
                AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type"},
                AllowCredentials: true,
                MaxAge: 12 * time.Hour,
        }))

Http client has headers for Content-Type: application/json and withCredentials: true
But it only sends OPTIONS request and then throws this error
{ _body: error, status: 0, ok: false, statusText: "", headers: Object, type: 3, url: null }

I tried different configurations for CORS and found following configuration which works well:

     r.Use(cors.New(cors.Config{
                AllowOrigins:     []string{"http://localhost:3000"},
                AllowMethods:     []string{"GET", "POST", "PUT", "HEAD"},
                AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type"},
                AllowCredentials: true,
                MaxAge: 12 * time.Hour,
        }))

But I need to allow all origins. What is the problem with enabling both AllowAllOrigins and AllowCredentials together?

Thanks

update README file

The latest version of cors.Config has fields Allowed instead of Allow and Exposed instead of Expose.
Eg: AllowedOrigins, AllowedMethods, AllowedHeaders and ExposedHeaders.

Allow All Headers

corsConfig = cors.DefaultConfig()
corsConfig.AllowOrigins = []string{"http://localhost:3000"}
corsConfig.AllowCredentials = true
corsConfig.AddAllowHeaders("Authorization") // Add any additional headers you need to allow
corsConfig.AddAllowHeaders("UserID")
corsConfig.AddAllowHeaders("UserType")

We are adding one one Headers manually like UserID and UserType. Can we don something that all the headers are allowed by default.

Asterisk wildcard does not work

Hello! I tried working with the most-recent master state of this project. Although the * wildcard for Access-Control-Allow-Origin (introduced last year, f894742) should allow for all origins, it does not: validateOrigin certainly does not check whether an asterisk is present (just a shallow equality check), although it is explicitly stated otherwise in the documentation:

If the special "*" value is present in the list, all origins will be allowed.

I could imagine fixing this by either adding a separate case into validateOrigin, checking for an asterisk value, or setting AllowAllOrigins to true if an asterisk is contained in AllowOrigins.

Besides that, I have two points, the former in relation to this issue:

  • I find AllowAllOrigins quite ambiguous, being just an edge case for specifying an asterisk wildcard. It does not reflect the CORS specification, and using an asterisk is much more verbose instead of using both attributes for specifying origins.
  • CORS does not imply validating Origin headers on the server side; it's rather the browsers who adhere to the CORS specification and validate requests. I would imagine a CORS middleware to simply add the respective CORS headers and possibly enable preflight requests, as the CORS middleware for Express does. I found the 403 Forbidden responses super confusing when having invalid Origin values. Maybe we could make server-side validation optional, or explicitly state that this module performs validation?

Error any time I try to download cors

Hi,

I,ve been tring to get cors using go "get github.com/gin-contrib/cors" but Iḿ getting this error, could you please help me!

google.golang.org/protobuf/proto

../../../src/google.golang.org/protobuf/proto/proto_methods.go:18:23: cannot use m.ProtoMethods() (type *protoreflect.Message) as type *struct { pragma.NoUnkeyedLiterals; Flags uint64; Size func(struct { pragma.NoUnkeyedLiterals; Message protoreflect.Message; Flags uint8 }) struct { pragma.NoUnkeyedLiterals; Size int }; Marshal func(struct { pragma.NoUnkeyedLiterals; Message protoreflect.Message; Buf []byte; Flags uint8 }) (struct { pragma.NoUnkeyedLiterals; Buf []byte }, error); Unmarshal func(struct { pragma.NoUnkeyedLiterals; Message protoreflect.Message; Buf []byte; Flags uint8; Resolver interface { FindExtensionByName(protoreflect.FullName) (protoreflect.ExtensionType, error); FindExtensionByNumber(protoreflect.FullName, protowire.Number) (protoreflect.ExtensionType, error) } }) (struct { pragma.NoUnkeyedLiterals; Flags uint8 }, error); Merge func(struct { pragma.NoUnkeyedLiterals; Source protoreflect.Message; Destination protoreflect.Message }) struct { pragma.NoUnkeyedLiterals; Flags uint8 }; CheckInitialized func(struct { pragma.NoUnkeyedLiterals; Message protoreflect.Message }) (struct { pragma.NoUnkeyedLiterals }, error) } in return argument

I tried downloading just the files but im still getting this message, iḿ new with this so i would really appreciate your help!

"null" origin should be allowed

According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin the header may be one of:

Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: <origin>
Access-Control-Allow-Origin: null

However, when I try to specify "null" as one of the origins:

r.Use(cors.New(cors.Config{
		AllowOrigins: []string{
...
			"null",
		},

I get:

panic: bad origin: origins must contain '*' or include http://,https://

The use case is PWA sharing files on Android using POST to the app - in that case we get "null" in the Origin header. I saw that it's not recommended, however I think it should be supported as an option.

Best regards

Łukasz Tomaszkiewicz

cors config AllowOrigins bug

Below is the source code

	// AllowedOrigins is a list of origins a cross-domain request can be executed from.
	// If the special "*" value is present in the list, all origins will be allowed.
	// Default value is ["*"]
	AllowOrigins []string

AllowOrigins default value is [*], If I do not specify it,I run into error:

panic: conflict settings: all origins disabled

If I specify it AllowOrigins: []string{"*"}, I run into error:

panic: bad origin: origins must include http:// or https://

So I think below code should support AllowOrigins default value ["*"]

func (c Config) Validate() error {
	if c.AllowAllOrigins && (c.AllowOriginFunc != nil || len(c.AllowOrigins) > 0) {
		return errors.New("conflict settings: all origins are allowed. AllowOriginFunc or AllowedOrigins is not needed")
	}
	if !c.AllowAllOrigins && c.AllowOriginFunc == nil && len(c.AllowOrigins) == 0 {
		return errors.New("conflict settings: all origins disabled")
	}
	for _, origin := range c.AllowOrigins {
		if !strings.HasPrefix(origin, "http://") && !strings.HasPrefix(origin, "https://") {
			return errors.New("bad origin: origins must include http:// or https://")
		}
	}
	return nil
}

Above just my personal opition:)

Not working with gopkg Gin import

import (
  "gopkg.in/gin-contrib/cors.v1"
  "gopkg.in/gin-gonic/gin.v1"
)

func main() {
  	app := gin.Default()
	app.Use(cors.Default())  // NOPE - type mismatch
}

changing the import to github directly makes it ok:

import (
  "gopkg.in/gin-contrib/cors.v1"
  "github.com/gin-gonic/gin"
)

func main() {
  	app := gin.Default()
	app.Use(cors.Default())  // OK
}

I can't use cors.default() to allow all origin haeder.

In this case i am using react axios get request method to my api in these code below you can see i use r.Use(cors.Default()) but my react show error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

func main() {
	//disable [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
	//gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.Use(cors.Default())

	PORT := v.GetInt("SERVER.PORT")
	err := r.Run(fmt.Sprintf(":%v", PORT))
	if err != nil {
		logs.Error(err)
		panic(err)
	} else {
		logs.Info(fmt.Sprintf("server is runing at port : %v", PORT))
	}
}

What should i use for fix it.

Thank you very much.

Access-Control-Allow-Headers CORS Error

I am trying to use the below code to upload my file using Uppy. However, When I am trying to do that, I'm getting CORS origin error.
Output in console : [GIN] 2020/11/21 - 00:56:46 | 204 | 337.339µs | ::1 | OPTIONS "/files/"
This is the error I am getting in my browser's console : "'http://localhost:8080/files/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field tus-resumable is not allowed by Access-Control-Allow-Headers in preflight response."
I used router.Use(cors.Default()) as well

router.POST("/files", func(c *gin.Context) {

		s3Locker := s3store.New("edisontestbucket1", s3.New(session.Must(session.NewSession()), s3Config))
		composer := tusd.NewStoreComposer()
		s3Locker.UseIn(composer)

		handler, err := tusd.NewHandler(tusd.Config{
			BasePath:              "/files/",
			StoreComposer:         composer,
			NotifyCompleteUploads: true,
			// NotifyTerminatedUploads: true,
			// NotifyUploadProgress:    true,
			// NotifyCreatedUploads:    true,
		})
		if err != nil {
			panic(fmt.Errorf("Unable to create handler: %s", err))
		}
		go func() {
			for {
				event := <-handler.CompleteUploads
				fmt.Printf("Upload %s finished\n", event.Upload.ID)
			}
		}()
	})

Consider archiving this repository, and pointing folks to github.com/rs/cors instead.

This package appears as the top search result on Google for gin gonic cors, but has a number of trouble spots that make it hard to use correctly the first time. I'm sure there's a good reason for the design, but the README doesn't make its gotchas obvious.

  • The Origin header issue
  • The explicit OPTIONS handler issue
  • The "does not work at the group level" issue

Instead, consider pointing users to https://github.com/rs/cors and its gin-gonic example.

Invalid on the new Gin version

When i use the new gin version (git master), the cors middleware can not work ok, the OPTIONS's response header is wrong.

I use the same code to test the old and new gin version with cors middleware.

old version response header:
Access-Control-Allow-Headers: content-type,tk
Access-Control-Allow-Methods: get,post,put,head
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 43200
Date: Tue, 26 Apr 2016 08:02:58 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

new version response header:
Date: Tue, 26 Apr 2016 07:58:53 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

unable to run example on the latest gin version, cannot use cors.New(config) as type HandlerFunc

i am trying to use the cors middleware on the latest gin version

./main.go:17: cannot use cors.New(config) (type "gopkg.in/gin-gonic/gin.v1".HandlerFunc) as type "github.com/gin-gonic/gin".HandlerFunc in argument to r.Use

where

r := gin.New()
config := cors.DefaultConfig()
config.AllowOrigins = []string{"http://google.com"}

r.Use(cors.New(config))
r.POST("/api/auth", api.Login)
r.Run()

Operating System: Mac OS X

Duplicate headers

I'm seeing duplicate cors headers on some of my requests:

image

I'm also using a cache middleware, so my guess is, the cached request already has the headers and cors is just adding them again?

config.Validate modifies the config itself

The behaviour was introduced in #47. While it allows * to be handled specially in AllowOrigins, it also means calling config.Validate twice may return different results. For example, this code panics:

corsConfig := cors.Config{
	AllowOrigins: []string{"*"},
	AllowMethods: []string{
		http.MethodGet,
		http.MethodHead,
		http.MethodPost,
		http.MethodPut,
		http.MethodPatch,
		http.MethodDelete,
	},
	AllowHeaders: []string{"Content-Type"},
}
if err := corsConfig.Validate(); err != nil {
	return err
}
corsHandler := cors.New(corsConfig)
panic: conflict settings: all origins are allowed. AllowOriginFunc or AllowOrigins is not needed

I think the handling of * should be moved to cors.New, and config.Validate should just consider * to be a valid value without changing any fields. Having a validation function changing the value passed in is unlikely an expected behaviour for most users.

Users currently cannot allow methods that are not uppercase

The Fetch standard states that methods are, in general, case-sensitive. For instance, PATCH is distinct from patch.

However, Gin's CORS middleware currently uppercases the allowed methods before writing the result in the Access-Control-Allow-Methods. Therefore, Gin's CORS middleware prevents its users from allowing methods that are not already uppercase.

Accordingly, two currently passing test cases, TestGeneratePreflightHeaders_AllowMethods and TestPassesAllowOrigins, should actually fail, because their assertions on w.Header().Get("Access-Control-Allow-Methods") are incorrect.

FWIW, this undue case-normalisation can be deplored in other CORS middleware libraries and it tends to trip users up. Gin should fixed this.

gin.Default() didn't allow all origins actually

If we want to allow all origins on CORS policy, we will find the code block on gin.Default().

func Default() gin.HandlerFunc {
	config := DefaultConfig()
	config.AllowAllOrigins = true
	return New(config)
}

The code block contains config.AllowAllOrigins = true, so we thought we don't have to change anything for allowing all origin, but we found something weird. We have to set AllowWildCard = true or AllowAllOrigin will not work, because AllowAllOrigin passes wildcard(*) on preflight request.

Maybe we should remove config.AllowAllOrigins = true from gin.Default()?

OPTIONS Verb 404

Here is my main app code:

package main

import (
	"bitbucket.org/frobl-inc/padsd/configuration"
	"time"

	"gopkg.in/gin-contrib/cors.v1"
	"gopkg.in/gin-gonic/gin.v1"
)

var config = configuration.Current

//Log is the main logger
var Log = configuration.Log

func main() {
	router := gin.Default()
	// CORS for https://foo.com and https://github.com origins, allowing:
	// - PUT and PATCH methods
	// - Origin header
	// - Credentials share
	// - Preflight requests cached for 12 hours
	router.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"https://foo.com"},
		AllowMethods:     []string{"PUT", "PATCH"},
		AllowHeaders:     []string{"Origin"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		AllowOriginFunc: func(origin string) bool {
			return origin == "https://github.com"
		},
		MaxAge: 12 * time.Hour,
	}))

	router.GET("/pads/healthcheck", healthCheck)

	router.Run()
}

When using a REST client (Postman) and executing the OPTIONS verb against /pads/healthcheck, the server returns a 404.

What am I doing wrong?

Weird Access-Control-Allow-Headers CORS Bug

I have a path to create a user: "/api/user." When I try to fetch it, I encounter an Access-Control-Allow-Headers block. However, when I change the path to "/api/user/create," it works fine.

Bug Code:

func Routes(router *gin.Engine, db *gorm.DB) {
	controller := Controller{
		Db: db,
	}
	r := router.Group("/api/user")
	r.GET("", controller.CreateUser)
}

image

Works Code:

func Routes(router *gin.Engine, db *gorm.DB) {
	controller := Controller{
		Db: db,
	}
	r := router.Group("/api/user")
	r.GET("/create", controller.CreateUser)
}

image

CORS config:

router.Use(cors.New(cors.Config{
	AllowOrigins:     []string{"http://localhost:3000"},
	AllowMethods:     []string{"GET", "POST", "PUT", "DELETE"},
	AllowHeaders:     []string{"Content-Type"},
	ExposeHeaders:    []string{"Content-Length"},
	AllowCredentials: true,
	AllowOriginFunc: func(origin string) bool {
		return origin == "http://localhost:3000"
	},
	MaxAge: 12 * time.Hour,
}))

[Notice] Preflight with no origin will return OPTIONS 404

Now you can see there is no [Origin] in my OPTIONS Request
image

And At Here

cors/config.go

Lines 58 to 62 in 5f50d4f

origin := c.Request.Header.Get("Origin")
if len(origin) == 0 {
// request is not a CORS request
return
}

The code will return and do nothing. Will Not Return Headers.

So If you not define OPTIONS Router, you will get 404 immediately.

Example does not seem to work?

Hello there, new to go so I am learning as I go sort of translating a small api app from other languages.

I will need to have cors, so rather than building my own middleware, I thought to give this a go, but looks like something is not working properly, maybe gin changed the way middlewares are provided? can't see anything around not even on the issues.

basically my code looks like this

package main

import (
	"net/http"

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

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

	config := cors.DefaultConfig()
	config.AllowOrigins = []string{"*"}
	router.Use(cors.New(config))

	router.GET("/ping", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})

	router.Run()
}

and I expect this to return the Allow Origins Headers, but I only get this

% http get http://localhost:8080/ping
HTTP/1.1 200 OK
Content-Length: 41
Content-Type: application/json; charset=utf-8
Date: Thu, 13 Aug 2020 11:54:48 GMT

{
    "message": "pong"
}

am I doing something wrong?
In the example you can only see the middleware being Used by the router, not the example route, I tried to place it before, and after the middleware declaration, but still nothing.

What am I doing wrong? Maybe is worth updating the doc to showcase an example with a route call?

thanks in advance

Missing Vary header

When used with a cache in front of the server and requests made from a context that requires CORS and one that doesn't you can receive bad responses for the request that requires CORS.

This can be fixed by adding "Vary: Origin" to all responses.

Shouldn't Be Returning * When Allow-Credentials and Allow-All-Origins are Set to True

https://github.com/gin-contrib/cors/blob/master/config.go#L88

Currently, if you are sending credentials, you need the OPTIONS request to send back a response with Access-Control-Allow-Origin: "" instead of Access-Control-Allow-Origin: "*" . This leads me to believe that this ! was added accidentally.

// line 88 in config.go
if !cors.allowAllOrigins {
	c.Header("Access-Control-Allow-Origin", origin)
}

// should be
if cors.allowAllOrigins {
	c.Header("Access-Control-Allow-Origin", origin)
}

Wildcard CORS

I have the code below:

	r := gin.New()
	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = []string{"https://*banterbus.netlify.app", "https://banterbus.games", "https://core.api.banterbus.games"}
	r.Use(cors.New(corsConfig))

As far as I can tell https://*banterbus.netlify.app does not seem to work however something like https://22--banterbus.netlify.app/ does work. How can I resolve this issue, to use wildcard/regex domain names. I'm using netlify branch deploys so the first part of the domain can vary.

Thanks

No way to disable caching of CORS-preflight responses

Omitting the Access-Control-Max-Age header from a preflight response leads browsers to cache that response for 5 seconds, whereas including

Access-Control-Max-Age: 0

in a preflight response instructs browsers not to cache that preflight response. However, Gin's CORS middleware ignores that distinction and takes a MaxAge value of 0 as a cue to omit the Access-Control-Max-Age header. Therefore, Gin's CORS middleware prevents its users from disabling caching of preflight responses.

Using allow all origins with credentials.

Take the following configuration.

func cors() gin.HandlerFunc {
	return ginCors.New(ginCors.Config{
		AllowAllOrigins:  true,
		AllowMethods:     []string{"GET", "PUT", "PATCH", "POST", "DELETE"}, // Allow all the methods above.
		AllowHeaders:     []string{"Origin", "Authorization", "Content-Type", "Accept", "Content-Length"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		MaxAge:           12 * time.Hour,
	})
}

When given a regular cross site request it works fine, however when you're using with credentials I get the following.

Failed to load http://{testing}/iam/check: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:8080' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

By looking at the code if AllowAllOrigins is enabled it will just always output * as the allow origin header.

I've done this in a different repository by sending everything up to the path from the referrer for example http://localhost:8080.

gin.v1 instead of gin

In this new update you change the gin framework version
"github.com/gin-gonic/gin" instead of "gopkg.in/gin-gonic/gin.v1"

So I'm getting this error:
cannot use cors.Default() (type "github.com/gin-gonic/gin".HandlerFunc) as type "gopkg.in/gin-gonic/gin.v1".HandlerFunc in argument to server.router.Use

Is this an issue or you change it in purpose ?

Can we change the cores handler to a non-anonymous function?

We used gin and this cores package. I found a problem that the cores handler is a anonymous
handler, and this causes a problem that we use the function's to auto statistic api's cost time. Cores handler will show func1, so I'm considering if we can change the function like this:

func New(config Config) gin.HandlerFunc {
	cors := newCors(config)
	return cors.applyCors(c)
}

CORS error with added header

I am developing application with react js. My every api call returns cors error. I tried my level best to tweak the settings.
Though router.Use(cors.Default()) works, but it is lacking several default headers like Auth token.
My setting as per the documentation is

router := gin.New()
// router.Use(cors.Default())

router.Use(cors.New(cors.Config{
	AllowOrigins: []string{"http://localhost:3000"},
	AllowMethods: []string{"PUT", "PATCH", "GET", "POST"},
	AllowHeaders:     []string{"Origin", "content-type", "x-csrf-token", "token"},
	// AllowHeaders:     []string{"content-type", "token"},
	ExposeHeaders:    []string{"Content-Length"},
	AllowCredentials: true,
	AllowOriginFunc: func(origin string) bool {
		return origin == "https://github.com"
	},
	MaxAge: 12 * time.Hour,
}))

React call too api is

const submitUrl = "http://localhost:8012/v1/user";
try {
const res = await fetch(submitUrl, {
method: "GET",
headers: {
token: token,
"Content-Type": "application/json",
},
});
if (res.status == 200) {
const data = await res.json();
setUser(data);
} else {
localStorage.removeItem("token");
}
} catch (err) {
console.log("Error " + err);
}

React app is running on localhost:3000. If anyone can help out to solve this cors error would be great, otherwise I will have to set proxy setting at react js.

React & React Native Issue

To be honest this one is really annoys me a lot I tried everything to get data from my gin api's to my React App nothing worked I even specifically declared "OPTIONS" inside of allowmethods didn't even worked until this trick
// config.AddAllowMethods("OPTIONS")
and now I'm facing same problem with react native and I'm really curious your documentation (which poorly designed) should mention those tricks even if you are not capable of the solve the problem otherwise you will lose most of the users in the beginning

c.Next() call missing in applyCors() function call

Per gin's documentation every middleware should call c.Next() to pass the request to the next middleware registered. But I did not find the usage / call of Next() in any of the code.

May I know how this is working?
Relevant code:

func (cors *cors) applyCors(c *gin.Context) {
	origin := c.Request.Header.Get("Origin")
	if len(origin) == 0 {
		// request is not a CORS request
		return
	}
	host := c.Request.Host

	if origin == "http://"+host || origin == "https://"+host {
		// request is not a CORS request but have origin header.
		// for example, use fetch api
		return
	}

	if !cors.validateOrigin(origin) {
		c.AbortWithStatus(http.StatusForbidden)
		return
	}

	if c.Request.Method == "OPTIONS" {
		cors.handlePreflight(c)
		defer c.AbortWithStatus(http.StatusNoContent) // Using 204 is better than 200 when the request status is OPTIONS
	} else {
		cors.handleNormal(c)
	}

	if !cors.allowAllOrigins {
		c.Header("Access-Control-Allow-Origin", origin)
	}
}

[handlePreflight] AbortWithStatus should be come after setting preflightHeaders

func handlePreflight(c *gin.Context, s *settings) bool {
	c.AbortWithStatus(200)
	if !s.validateMethod(c.Request.Header.Get("Access-Control-Request-Method")) {
		return false
	}
	if !s.validateHeader(c.Request.Header.Get("Access-Control-Request-Header")) {
		return false
	}
	for key, value := range s.preflightHeaders {
		c.Writer.Header()[key] = value
	}
	return true
}

When the Options method requested, the browser returns:
image

But I Allow this method and headers:

CorsMws = cors.New(cors.Config{
		AllowedOrigins: []string{conf.WebAddress},
		AllowedMethods: []string{"GET", "POST", "OPTIONS", "PUT", "DELETE", "UPDATE"},
		AllowedHeaders: []string{"Authorization", "Content-Type", "Upgrade", "Origin",
			"Connection", "Accept-Encoding", "Accept-Language", "Host", "Access-Control-Request-Method", "Access-Control-Request-Headers"},
		ExposedHeaders: []string{"Content-Length"},
		MaxAge:         12 * time.Hour,
})

Rejected OPTIONS request when OPTIONS is configured in cors.

Description

Having cors configurated in order to accept CORS requests, when sending an multipart/form-data, the following appears: Access to XMLHttpRequest at 'http://localhost:8080/add_project' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

How to reproduce

package main

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

func add_project(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")

	// Connection to the database
	db := initDB()

	var newProject project

	claims, err := encryption.GetClaims(encryption.GetToken(c))
	if err != nil {
		c.JSON(http.StatusBadRequest, nil)
		return
	}

	if err := c.BindJSON(&newProject); err != nil {
		return
	}
	if claims["username"] == "erikdz" {
		statement, _ := db.Prepare("INSERT INTO projects (name, date, state, abandoned, description, image) VALUES (?, ?, ?, ?, ?, ?)")
		statement.Exec(newProject.Name, newProject.Date, newProject.State, newProject.Abandoned, newProject.Description, newProject.Image)
		c.JSON(http.StatusAccepted, nil)
	} else {
		c.JSON(http.StatusUnauthorized, nil)
	}
	// Close connection database
	defer db.Close()
}


func main() {
	router := gin.Default()
	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = []string{"http://localhost:3000"}
	// To be able to send tokens to the server.
	corsConfig.AllowCredentials = true
	// OPTIONS method for ReactJS
	corsConfig.AddAllowMethods("OPTIONS")
	router.Use(cors.New(corsConfig))

	router.POST("/add_project", add_project)

	router.Run("localhost:8080")

}

React code:

   if (formIsValid){
    var formData = new FormData();

     formData.append('file', this.state.image)
     formData.append('data', {
                              name:this.state.name,
                              state:this.state.state,
                              date: this.state.date,
                              description: this.state.description,
                              abandoned: this.state.abandoned
                            })
    axios({
      method: "post",
      url: process.env.REACT_APP_API_DOMAIN + "/add_project",
      data: formData,
      headers: { "Content-Type": "multipart/form-data", "Authorization" : `Bearer ${this.state.jwttoken}` },
    })
      .then(function (response) {
        //handle success
        console.log(response);
      })
      .catch(function (response) {
        //handle error
        console.log(response);
      });
   }

Expectations

200 StatusAccepted

Actual result

Access to XMLHttpRequest at 'http://localhost:8080/add_project' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

$ curl -i -X OPTIONS http://localhost:8080/add_project
   -H "Access-Control-Request-Method: POST"
   -H "Access-Control-Request-Headers: content-type"
   -H "Origin: https://reqbin.com"

HTTP/1.1 403 Forbidden
Date: Sun, 01 Aug 2021 09:45:18 GMT
Content-Length: 0


404 page not found

Environment

go version: go version go1.13.8 linux/amd64
gin version (or commit ref): latest
operating system: ubuntu 20.04

middleware can't be apply on a router group

The following gives 404:

package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"

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

func main() {
	router := gin.Default()
	c := cors.Default()
	var g gin.IRoutes
	g = router.Group("/")
	g = g.Use(c)
	g.GET("/", func(c *gin.Context) {
		c.String(200, "ok")
	})

	serve(router)
}

func serve(h http.Handler) {
	r := httptest.NewRequest(http.MethodOptions, "http://service.example.com", nil)
	r.Header.Set("Origin", "http://www.example.com")
	r.Header.Set("Access-Control-Request-Method", "POST")

	w := httptest.NewRecorder()
	h.ServeHTTP(w, r)
	b, _ := httputil.DumpResponse(w.Result(), true)
	fmt.Println(string(b))
}

Snyk vulnerability HTTP Response Splitting on older version of github.com/gin-gonic/gin

We are using the latest version of https://github.com/gin-contrib/[email protected] which internally uses the gin-gonic library and the version is github.com/gin-gonic/[email protected] in go.mod

This has introduced snyk vulnerability HTTP Response Splitting with the following path:
Introduced through: [email protected] › github.com/gin-contrib/[email protected] › github.com/gin-gonic/[email protected]

Snyk link issue: https://security.snyk.io/vuln/SNYK-GOLANG-GITHUBCOMGINGONICGIN-1041736

In master branch in go.mod, I see gin-gonic version has been upgraded to v1.8.1

What is the estimated date to release this master branch changes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.