CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

huangapple go评论78阅读模式
英文:

Cors React and Gin-Gonic Gin

问题

我在开发环境中遇到了一个问题,实现了React前端和Go语言Gin-Gonic框架之间的跨域资源共享。下面是浏览器控制台的日志:

CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

React应用程序发送POST请求的控制台日志:

这是Go框架接收到的请求,可以看到预检请求未经验证

我尝试了两种方法,一种是验证预检请求并在React的OPTIONS请求中返回200,如下所示:

func preflight(c *gin.Context) {
    c.Header("Access-Control-Allow-Origin", "*")
    c.Header("Access-Control-Allow-Headers", "access-control-allow-origin, access-control-allow-headers")
    c.JSON(http.StatusOK, struct{}{})
}

这种方法没有帮助,另外,我在访问控制允许的来源中包含了一个通配符域名的中间件,以及http://localhost:3000,如下所示:

func CORSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {

        c.Header("Access-Control-Allow-Origin", "*")
        c.Header("Access-Control-Allow-Credentials", "true")
        c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
        c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")

        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }

        c.Next()
    }
}

我还尝试了gin cors包,如此处所示:github.com/gin-contrib/cors,但请求仍然被阻止。

CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

这些是我的路由的一部分:

r := gin.Default()
//r := gin.New()

config := cors.DefaultConfig()
config.AllowOrigins = []string{"*"}
// config.AllowOrigins = []string{"http://google.com", "http://facebook.com"}
// config.AllowAllOrigins = true
r.Use(cors.New(config))

//system routes
router.NotFound(r)
router.NoMethods(r)

//static routes
router.ServeStatic(r)

这是我的路由方法:

func NotFound(route *gin.Engine) {
    route.NoRoute(func(c *gin.Context) {
        c.JSON(404, gin.H{"msg": "Not Found"})
    })
}

func NoMethods(route *gin.Engine) {
    route.NoMethod(func(c *gin.Context) {
        c.JSON(405, gin.H{"msg": "Not allowed"})
    })
}

//Serve frontend static files

func ServeStatic(route *gin.Engine) {
    route.Use(static.Serve("/", static.LocalFile("./views/public", true)))
    route.Use(auth.CORSMiddleware())
    api := route.Group("/api")

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

Go版本是go1.18.1 linux/amd64

"axios": "^0.24.0",
"react": "^18.1.0"

英文:

I have run into a problem implementing cross origin resource sharing in the development environment, between a react front end and Go-lang Gin-Gonic framework, below is the console log from the browser
CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

Console log from the react application sending a post request

This is the received request from the Go framework, as can be seen, the preflight request is not validated

I have attempted two hacks, one is validating the preflight request and passing a 200 on the react OPTIONS as seen below

func preflight(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("Access-Control-Allow-Headers", "access-control-allow-origin, access-control-allow-headers")
	c.JSON(http.StatusOK, struct{}{})
}

This hack was not of help, additionally ,i included a middleware with a wildcard domain in the access control allow origin, as well as with http://localhost:3000 as shown below

func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {

		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Credentials", "true")
		c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

I also tried the gin cors package as shown here github.com/gin-contrib/cors but the request is still being blocked

CORS是跨源资源共享的缩写,React和Gin-Gonic Gin是两个框架的名称。

These are part of my routes 

	r := gin.Default()
	//r := gin.New()

	config := cors.DefaultConfig()
	config.AllowOrigins = []string{"*"}
	// config.AllowOrigins = []string{"http://google.com", "http://facebook.com"}
	// config.AllowAllOrigins = true
	r.Use(cors.New(config))

	//system routes
	router.NotFound(r)
	router.NoMethods(r)

	//static routes
	router.ServeStatic(r)
Methods 

func NotFound(route *gin.Engine) {
	route.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{"msg": "Not Found"})
	})
}

func NoMethods(route *gin.Engine) {
	route.NoMethod(func(c *gin.Context) {
		c.JSON(405, gin.H{"msg": "Not allowed"})
	})
}

//Serve frontend static files

func ServeStatic(route *gin.Engine) {
	route.Use(static.Serve("/", static.LocalFile("./views/public", true)))
	route.Use(auth.CORSMiddleware())
	api := route.Group("/api")

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

The go version is go version go1.18.1 linux/amd64

"axios": "^0.24.0",
"react": "^18.1.0",

答案1

得分: 1

尝试将CORS中间件移动到handleFunc之前。

示例:

func (h *Handler) InitRoutes() *gin.Engine {
    router := gin.New()

    router.Use(h.setHeaders)

    router.GET("/", h.getRecordsByFilter)
    router.GET("/:uuid", h.getRecordByUuid)
    router.POST("/", h.createRecord)
    router.PUT("/:uuid", h.updateRecord)
    router.DELETE("/:uuid", h.deleteRecord)

    return router
}

请注意,这是一个示例代码片段,你需要根据自己的实际情况进行相应的修改。

英文:

Try to move CORS middleware before your handleFunc

Example:

func (h *Handler) InitRoutes() *gin.Engine {
    router := gin.New()

    router.Use(h.setHeaders)

    router.GET("/", h.getRecordsByFilter)
    router.GET("/:uuid", h.getRecordByUuid)
    router.POST("/", h.createRecord)
    router.PUT("/:uuid", h.updateRecord)
    router.DELETE("/:uuid", h.deleteRecord)

    return router
}

答案2

得分: 0

问题出在来自React前端的凭据上。

handleSubmit(event) {
const {email,password} = this.state;
axios.post("http://localhost:3000/auth/register",
{email: email, password: password},{
withCredentials: true}).then(response => {
console.log("registration res", response);
console.log("response data",response.data);
}).catch(error => {
console.log("registration error", error);
});

event.preventDefault();

}

英文:

The problem was with credentials true from the react front-end

handleSubmit(event) {
    const {email,password} = this.state;
    axios.post("http://localhost:3000/auth/register",
    {email: email, password: password},{
        withCredentials: true}).then(response => {
            console.log("registration res", response);
            console.log("response data",response.data);
        }).catch(error => {
            console.log("registratino error", error);
        });


    event.preventDefault();
}

huangapple
  • 本文由 发表于 2022年5月10日 14:56:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/72181878.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定