This is the first day of my participation in the Gwen Challenge in November. Check out the details: the last Gwen Challenge in 2021
A preface.
Gin middleware can be used in a wide range of scenarios. This section describes how to use gin middleware for authentication in common scenarios.
Ii. Official documents
The official documentation lists the following ways:
- Using middleware
- Custom middleware
- Middleware that uses basic authentication
- Middleware uses coroutines
Authentication implementation in different scenarios
1. api key
For the API key mode, you need to set a whitelist and perform token detection for requests that are not included in the whitelist. This middleware intercepts the request to validate the token before it is processed, so you can use gin.Context to set the Context, such as the user information of the user to which the request belongs.
package middleware
import (
"fmt"
"net/url"
"strings"
"github.com/gin-gonic/gin"
)
func whiteList(a) map[string]string {
return map[string]string{
"/ping": "GET",}}func withinWhiteList(url *url.URL, method string) bool {
target := whiteList()
queryUrl := strings.Split(fmt.Sprint(url), "?") [0]
if _, ok := target[queryUrl]; ok {
if target[queryUrl] == method {
return true
}
return false
}
return false
}
func Authorize(a) gin.HandlerFunc {
return func(c *gin.Context) {
type QueryToken struct {
Token string `binding:"required,len=3" form:"token"`
}
// Token check is performed when the route is not in the whitelist
if! withinWhiteList(c.Request.URL, c.Request.Method) {var queryToken QueryToken
ifc.ShouldBindQuery(&queryToken) ! =nil {
c.AbortWithStatusJSON(200, gin.H{
"code": 40001,})return
}
c.Set("role"."user")
}
c.Next()
}
}
Copy the code
2. Route permission
1)
For the processing of a request, you need to verify that you have access to the requested path.
Take a look at gin’s routing Settings first:
func (group *RouterGroup) POST(relativePath string, handlers ... HandlerFunc) IRoutes
Copy the code
Its parameter is… HandlerFunc, which is interpreted as:
type HandlerFunc func(*Context)
HandlerFunc defines the handler used by gin middleware as return value.
Copy the code
So you can implement a route permission processing by customizing the middleware.
Of course, the permission processing here is relatively simple, use the role to directly determine the permission. For example, there are two roles: administrator admin and common user.
However, there is a prerequisite for this implementation, which is how to get the user’s role? Here we need to add to the implementation of the previous step (API key) that sets the role using gin.Context:
c.Set("role"."admin") // See the code from the previous step, of course, only here to demonstrate setting fixed values
Copy the code
Then get the character in the middleware and decide.
2) Routing permission middleware
package middleware
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
)
func Permissions(roles []string) gin.HandlerFunc {
return func(c *gin.Context) {
permissionsErr := func(a) error {
// Get the user role in the context
roleValue, exists := c.Get("role")
if! exists {return errors.New("Failed to obtain user information")
}
role := fmt.Sprint(roleValue)
// Determine whether the requested user's role belongs to the set role
noAccess := true
for i := 0; i < len(roles); i++ {
if role == roles[i] {
noAccess = false}}if noAccess {
return errors.New("Insufficient authority")}return nil} ()ifpermissionsErr ! =nil {
c.AbortWithStatusJSON(200, gin.H{
"code": 40001,})return
}
c.Next()
}
}
Copy the code
3) use
When setting the route, add the middleware and set the whitelist.
r.POST("/todo", middleware.Permissions([]string{"admin"}), views.AddTodo) // Adding middleware will validate roles
r.PUT("/todo", views.ModifyTodo) // Roles are not validated if middleware is not added
Copy the code
4. Original blog links
- Gin middleware and authentication