GNext is impressive but uses interface{} as the handler type. The good part is that we're flexible on how to write handlers. The bad part is how hard it is to write any function that wraps handlers in general.
The code below is an example of what I want to achieve:
router.GET("/endpoint", WithAuth(myHandler, roleAdmin, roleUser))
router.POST("/endpoint", WithAuth(myHandler, roleAdmin))
Writing the WithAuth wrapper is more challenging than I thought because there's no handler type. It would require several runtime checks and reflect uses, making the code very unclear.
Here's how I am doing it:
authMiddlewareAdmin := AuthMiddleware{}
authMiddlewareAdmin.AddAllowedRoles(roleAdmin)
adminOnlyGroup := router.Group("")
adminOnlyGroup.Use(gnext.Middleware{
Before: authMiddlewareAdmin.Before,
}
adminOnlyGroup.POST("/endpoint", myHandler)
authMiddlewareAdminUser := AuthMiddleware{}
authMiddlewareAdminUser.AddAllowedRoles(roleAdmin, roleUser)
userAdminGroup := router.Group("")
userAdminGroup.Use(gnext.Middleware{
Before: authMiddlewareAdminUser.Before,
}
userAdminGroup.GET("/endpoint", myHandler)
This needs to be more scalable. If you have five roles, you need 5! objects of AuthMiddleware to represent every combination.
I have opened this issue to gather opinions from the contributors on how to improve this code. It would be relatively easy with pure Gin, but I'd lose all the benefits from GNext. Please let me know if you have any questions or suggestions.
Here's one idea I have in mind: building a permissions matrix. Instead of declaring allowed roles on a handler level, I'd do it in another package. It's a matrix of endpoints and roles.
|
/endpoint |
/anotherEndpoint |
| Admin |
Allow |
Allow |
| User |
Deny |
Allow |
I'd add another dimension for the HTTP method. However, it takes a lot of work to represent 3D in markdown. It's a scalable solution, as far as I know. We could even have a standard authorization module on GNext.
GNext is impressive but uses
interface{}as the handler type. The good part is that we're flexible on how to write handlers. The bad part is how hard it is to write any function that wraps handlers in general.The code below is an example of what I want to achieve:
Writing the
WithAuthwrapper is more challenging than I thought because there's no handler type. It would require several runtime checks andreflectuses, making the code very unclear.Here's how I am doing it:
This needs to be more scalable. If you have five roles, you need
5!objects ofAuthMiddlewareto represent every combination.I have opened this issue to gather opinions from the contributors on how to improve this code. It would be relatively easy with pure Gin, but I'd lose all the benefits from GNext. Please let me know if you have any questions or suggestions.
Here's one idea I have in mind: building a permissions matrix. Instead of declaring allowed roles on a handler level, I'd do it in another package. It's a matrix of endpoints and roles.
/endpoint/anotherEndpointI'd add another dimension for the HTTP method. However, it takes a lot of work to represent 3D in markdown. It's a scalable solution, as far as I know. We could even have a standard authorization module on GNext.