gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78k stars 7.97k forks source link

CORS Issue with Basic Auth #1799

Open 5a3o opened 5 years ago

5a3o commented 5 years ago

Description

CORS issue when Basic Auth is enabled on a group Added two routes,

  1. /api/v1/application -- No Basic Auth -- WORKS
  2. /api/v2/application --Basic Auth ENABLED -- CORS ISSUE

Error Message On Client: Access to XMLHttpRequest at 'http://localhost:8080/api/v2/application' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Screenshots

image

Code Attached

main.txt

CODE

package main

import (
    "fmt"

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

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

    r.Use(CORSMiddleware())

    v1 := r.Group("/api/v1/")
    {
        v1.GET("/application", resp1)
    }

    authorized := r.Group("/api/v2/", gin.BasicAuth(gin.Accounts{
        "Admin": "Admin",
    }))

    v2 := authorized.Group("/application")
    {
        v2.GET("/", resp)
    }

    r.Run() // listen and serve on 0.0.0.0:8080
}

func resp(c *gin.Context) {

    c.JSON(200, gin.H{
        "message": "pong",
    })
}

func resp1(c *gin.Context) {

    if c.Request.Method == "OPTIONS" {
        fmt.Println("OPTIONS")
        c.AbortWithStatus(200)
    } else {
        c.Next()
    }

    fmt.Println(c.Request.Method)

    c.JSON(200, gin.H{
        "message": "pong",
    })
}

func CORSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
        c.Writer.Header().Set("Access-Control-Max-Age", "86400")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Access-Control-Allow-Origin, Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
        c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
        c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

        fmt.Println(c.Request.Method)

        if c.Request.Method == "OPTIONS" {
            fmt.Println("OPTIONS")
            c.AbortWithStatus(200)
        } else {
            c.Next()
        }
    }
}
made2591 commented 5 years ago

I tested your code and it worked fine on both 'http://localhost:8080/api/v1/application' and 'http://localhost:8080/api/v2/application'. Have I covered your test scenario correctly?

0x2d3c commented 5 years ago

may you change c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000") to "c.Writer.Header().Set(Access-Control-Allow-Origin", c.Request.Header.Get("Origin")

yeahnoob commented 5 years ago

If in development enviroment, you can try to running the local test with

("Access-Control-Allow-Origin", "*") .

ghost commented 4 years ago

I had the same issue,

What's the root cause?

jackfischer commented 2 years ago

It appears this happens when the auth is missing or incorrect. Your function isn't evaluated and it doesn't write out the header.