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