Middleware Errors are NOT honored
Using oapi-codegen v1.11.0 to generate the server stub for the below spec
~/go/bin/oapi-codegen -package main -generate gin,types,spec -old-config-style schema.yaml > server.gen.go
paths:
/status:
get:
description: Get Status
operationId: GetStatus
parameters:
- name: token
in: header
description: Validation Token
required: true
schema:
type: string
responses:
'200':
description: Status OK
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
components:
schemas:
Status:
type: object
required:
- status
properties:
status:
type: string
In main.go, a token check middleware is added as a Gin Server Option
type handler struct {}
func (h *handler) GetStatus(c *gin.Context, params GetStatusParams) {
c.JSON(http.StatusOK, Status{Status: "ok"})
}
func main() {
swagger, _ := GetSwagger()
swagger.Servers = nil
r := gin.Default()
r.Use(middleware.OapiRequestValidator(swagger))
RegisterHandlersWithOptions(r, &handler{}, GinServerOptions{Middlewares: []MiddlewareFunc{tokenCheck}})
r.Run(":8081")
}
func tokenCheck(c *gin.Context) {
if c.GetHeader("token") == "my-token" {
c.Next()
return
}
c.AbortWithStatusJSON(http.StatusUnauthorized, Status{Status: "failure"})
}
Sample output
Success - correct token
$ curl -i -X GET http://localhost:8081/status -H "token: my-token"
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sun, 29 May 2022 18:33:21 GMT
Content-Length: 15
{"status":"ok"}
Undesired reponse - wrong token
$ curl -i -X GET http://localhost:8081/status -H "token: wrong-token"
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Date: Sun, 29 May 2022 18:33:27 GMT
Content-Length: 35
{"status":"failure"}{"status":"ok"}
From the code
https://github.com/deepmap/oapi-codegen/blob/b3eedde3c868b1b4c3f55e3283af30e0edd29c31/pkg/codegen/templates/gin/gin-wrappers.tmpl#L169
it seems no checks on middleware's call is being made.
Changing the MiddlewareFunc type to func(c *gin.Context) (err error) and acting according as per the returned error would honor the defined middleware in case of failures.
var err error
for _, middleware := range siw.HandlerMiddlewares {
err = middleware(c)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"msg": "Middleware failure: " + err.Error()})
return
}
}
Please let me know if this can be acheived through any other ways. Thank you.
@deepmap-marcinr Is there any way to Abort the request for a middlware failure ?
I think this issue is a duplicate of #485 and is fixed in #914 (in master, but not released yet)
I think this issue is a duplicate of #485 and is fixed in #914 (in master, but not released yet)
Agreed! #914 is also released now, so it should be ok to close this issue as resolved