r:=gin.Default()
r.GET("/baidu", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "https://baidu.com")
})
r.Run(":8089")
分组路由使代码逻辑更加模块化,同时也易于定义中间件的使用范围
v1 := router.Group("/v1")
v1.GET("/login", func(c *gin.Context) {
c.String(http.StatusOK, "v1 login")
})
v2 := router.Group("/v2")
v2.GET("/login", func(c *gin.Context) {
c.String(http.StatusOK, "v2 login")
})
先定义一个中间件函数:
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("before middleware")
c.Set("request", "clinet_request")
c.Next()
fmt.Println("before middleware")
}
}
该函数只会给c上下文添加一个属性,并赋值。后面的路由处理器,可以根据被中间件装饰后提取其值。需要注意,虽然名为全局中间件,只要是在注册中间件的过程之前设置的路由,将不会受注册的中间件所影响。只有注册了中间件以下代码的路由函数规则,才会被中间件装饰
router.Use(MiddleWare())
{
router.GET("/middleware", func(c *gin.Context) {
request := c.MustGet("request").(string)
req, _ := c.Get("request")
c.JSON(http.StatusOK, gin.H{
"middile_request": request,
"request": req,
})
})
}
使用router装饰中间件,然后在/middlerware
即可读取request的值,注意在router.Use(MiddleWare())
代码以上的路由函数,将不会有被中间件装饰的效果。
使用花括号包含被装饰的路由函数只是一个代码规范,即使没有被包含在内的路由函数,只要使用router进行路由,都等于被装饰了。想要区分权限范围,可以使用组返回的对象注册中间件。
# curl http://127.0.0.1:8000/middleware
{"middile_request":"clinet_request","request":"clinet_request"}
如果没有注册就使用 MustGet 方法读取c的值将会抛错,可以使用 Get 方法取而代之
上面的注册装饰方式,会让所有下面所写的代码都默认使用 router 注册过的中间件
当然,gin也提供了针对指定的路由函数进行注册。
router.GET("/before", MiddleWare(), func(c *gin.Context) {
request := c.MustGet("request").(string)
c.JSON(http.StatusOK, gin.H{
"middile_request": request,
})
})
把上述代码写在 router.Use(Middleware())之前,同样 /before
被装饰了中间件
群组的中间件也类似,只要在对应的群组路由上注册中间件函数即可:
authorized := router.Group("/", MyMiddelware())
// 或者这样用:
authorized := router.Group("/")
authorized.Use(MyMiddelware())
{
authorized.POST("/login", loginEndpoint)
}
群组可以嵌套,因为中间件也可以根据群组的嵌套规则嵌套
下面实现一个简易的鉴权中间件
router.GET("/auth/signin", func(c *gin.Context) {
cookie := &http.Cookie{
Name: "session_id",
Value: "123",
Path: "/",
HttpOnly: true,
}
http.SetCookie(c.Writer, cookie)
c.String(http.StatusOK, "Login successful")
})
router.GET("/home", AuthMiddleWare(), func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "home"})
})
登录函数会设置一个session_id的cookie,注意这里需要指定path为/
,不然gin会自动设置cookie的path为/auth
,一个特别奇怪的问题。/home
的逻辑很简单,使用中间件AuthMiddleWare注册之后,将会先执行AuthMiddleWare的逻辑,然后才到/home
的逻辑
AuthMiddleWare的代码如下:
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
if cookie, err := c.Request.Cookie("session_id"); err == nil {
value := cookie.Value
fmt.Println(value)
if value == "123" {
c.Next()
return
}
}
c.JSON(http.StatusUnauthorized, gin.H{
"error": "Unauthorized",
})
c.Abort()
return
}
}
从上下文的请求中读取cookie,然后校对cookie,如果有问题,则终止请求,直接返回,这里使用了c.Abort()方法
♥ 喜 欢 请 点 赞 哟 ♥ |
(●ˇ∀ˇ●) |