Golang Gin:中间件无效

发布于 2025-01-27 11:25:24 字数 2793 浏览 4 评论 0 原文

我从Frontend应用程序中收到了我的后端应用程序,请使用GIN编写的后端应用程序。我遇到了一个错误,说:

“不在请求的资源上存在''访问控制 - 允许孔'标题”

因此指出了我在后端应用中实现CORS。因此,我通过使用“ github.com/gin-contrib/cors”

web.go

func NewApp() *App {

    db := SetUpDB()
    router := gin.Default()

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

    return &App{
        Db:     db,
        Router: router,
    }
}

in main.go GOT:

app := core.NewApp()

    //app.Router.Use(CORS())

    defer func() {
        app.Db.Close()
        log.Printf("core: database stopping")
    }()

    app.Router.Use(func(c *gin.Context) {
        c.Set("db", app.Db)
    })

    app.Router.GET("/", func(ctx *gin.Context) {
        ctx.JSON(http.StatusOK, gin.H{"data": "welcome TEST"})
    })

    // Initialize all api routes
    routes.InitializeRoutes(app.Router.Group("/api/v1"))

您可以看到,我仅在允许methods 中设置 put ,目的是测试CORS实际上在工作。通过仅允许 put ,我期望允许除 put 以外的其他方法,但我错了。我已经从我的前端应用程序中执行了 get 请求(返回数据),这使我认为比CORS实现没有被拾取。

在浏览时,我发现人们不使用软件包“ github.com/gin-contrib/cors” 而是创建自己的中间件:

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

        fmt.Println(c.Request.Header)
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, Origin, Cache-Control, X-Requested-With")
        //c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "PUT, DELETE")

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

        c.Next()
    }
}

然后:

func NewApp() *App {

    db := SetUpDB()
    router := gin.Default()

    router.Use(CORS())

    return &App{
        Db:     db,
        Router: router,
    }
}

我也没有运气尝试过。相同的结果又回来了。

此外,当我执行 get 并在后端打印方法( c.request.method )时,结果是 get 。但是,当我执行发布并打印我获取的方法 options

我缺少什么?为什么路由器不使用提供的中间件?

I've got a POST request from my frontend app to my backend app written in Go using Gin. I was getting an error saying:

"No 'Access-Control-Allow-Origin' header is present on the requested resource"

so that pointed me to implement CORS in my backend app. So I did by using "github.com/gin-contrib/cors":

web.go:

func NewApp() *App {

    db := SetUpDB()
    router := gin.Default()

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

    return &App{
        Db:     db,
        Router: router,
    }
}

and in main.go I've got:

app := core.NewApp()

    //app.Router.Use(CORS())

    defer func() {
        app.Db.Close()
        log.Printf("core: database stopping")
    }()

    app.Router.Use(func(c *gin.Context) {
        c.Set("db", app.Db)
    })

    app.Router.GET("/", func(ctx *gin.Context) {
        ctx.JSON(http.StatusOK, gin.H{"data": "welcome TEST"})
    })

    // Initialize all api routes
    routes.InitializeRoutes(app.Router.Group("/api/v1"))

as you can see I only set PUT in AllowMethods with the intention of testing CORS was actually working. By allowing only PUT I was expecting no methods other than PUT were allowed but I was wrong. I've performed a GET request from my frontend app and it goes through (it returns data), this leads me to think than the CORS implementation is not being picked up.

While browsing around, I've found people not using the package "github.com/gin-contrib/cors" but creating their own middleware:

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

        fmt.Println(c.Request.Header)
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, Origin, Cache-Control, X-Requested-With")
        //c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "PUT, DELETE")

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

        c.Next()
    }
}

and then:

func NewApp() *App {

    db := SetUpDB()
    router := gin.Default()

    router.Use(CORS())

    return &App{
        Db:     db,
        Router: router,
    }
}

I tried this as well with no luck. Same results are coming back.

Furthermore, when I perform the GET and print the method in my backend (c.Request.Method) the result is GET. But when I perform a POST and print the method I'm getting OPTIONS

What am I missing? Why router is not using the provided middleware?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌若浮生 2025-02-03 11:25:24

这个问题有两个部分:

  1. Heiko上面指示了第一个:Get是一个简单的请求,因此始终将结果返回到此类请求中。

  2. 现在,在测试我的 post 后,我仍然遇到错误。我已经检查了CORS配置,在这里和那里更改内容只是为了发现类别的路线是定义的,例如:

categoryRouter.POST("/", controllers.CreateNewCategory)
categoryRouter.GET("/", controllers.ListAllCategories)

如您所见,有一个taeld /,它导致了我的请求要重定向并返回错误,因为该请求的URL为 http://127.0.0.1:8080/api/api/v1/categories 。我更新了路线:

categoryRouter.POST("", controllers.CreateNewCategory)
categoryRouter.GET("", controllers.ListAllCategories)

现在它正在按预期工作。

There are two pieces to this question:

  1. The first one was indicated above by Heiko: Get is a simple request so the result is always gonna be returned for these kind of requests.

  2. Now, after testing back my POST, I was still getting errors. I had checked over and over the CORS config, changing things here and there just to find out that the routes for Category were define such as:

categoryRouter.POST("/", controllers.CreateNewCategory)
categoryRouter.GET("/", controllers.ListAllCategories)

as you can see there is a trailing / which was causing my request to be redirected and an error to be returned since the url used for the request was http://127.0.0.1:8080/api/v1/categories. I updated the routes to be:

categoryRouter.POST("", controllers.CreateNewCategory)
categoryRouter.GET("", controllers.ListAllCategories)

and now it is working as expected.

十年不长 2025-02-03 11:25:24

仅检查标头的CORS请求,以了解无法从Javascript-html html页面(所谓的非简单请求)引起的 。对于仅使用标准标头诸如获取的简单请求,仅检查访问 - 控制 - 允许孔> 标题,并且 access> access-control-allow-hall-methods 标题>标头无角色扮演。

The Access-Control-Allow-Methods header is only checked for CORS requests that cannot result from a Javascript-less HTML page (so-called non-simple requests). For simple requests such as GET with only standard headers, only the Access-Control-Allow-Origin header is checked and the Access-Control-Allow-Methods header plays no role.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文