APIKeyMiddleware validates API key for protected endpoints. Swagger documentation endpoints (/swagger/*) are exempt from authentication to allow users to browse and test the API documentation freely.
(apiKey string)
| 38 | // Swagger documentation endpoints (/swagger/*) are exempt from authentication |
| 39 | // to allow users to browse and test the API documentation freely. |
| 40 | func APIKeyMiddleware(apiKey string) gin.HandlerFunc { |
| 41 | // Compare digests, not the raw values. ConstantTimeCompare returns |
| 42 | // early when the lengths are different, and that shows the length of |
| 43 | // the configured key. |
| 44 | expectedKey := sha256.Sum256([]byte(apiKey)) |
| 45 | return func(c *gin.Context) { |
| 46 | // Skip authentication for Swagger documentation endpoints |
| 47 | // This allows public access to API docs even when authentication is enabled |
| 48 | if strings.HasPrefix(c.Request.URL.Path, "/swagger/") { |
| 49 | c.Next() |
| 50 | return |
| 51 | } |
| 52 | |
| 53 | headerApiKey := c.GetHeader(APIKeyHeader) |
| 54 | |
| 55 | if headerApiKey == "" { |
| 56 | c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Missing API Key"}) |
| 57 | return |
| 58 | } |
| 59 | |
| 60 | headerKey := sha256.Sum256([]byte(headerApiKey)) |
| 61 | if subtle.ConstantTimeCompare(headerKey[:], expectedKey[:]) != 1 { |
| 62 | c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Wrong API Key"}) |
| 63 | return |
| 64 | } |
| 65 | |
| 66 | c.Next() |
| 67 | } |
| 68 | } |
no outgoing calls