跳到主要内容

中间件

本章节将介绍如何在 Go-Sail 中注册路由中间件。

引言

路由中间件介于请求的前置处理和后置处理之间,作为两者的桥梁。通常我们会将一些通用的处理措施(如身份验证)放在中间件中。

Go-Sail 以 Gin 作为 HTTP 服务引擎,未做过度封装,因此用法与 Gin 完全一致。

在上一章节中,用户登录成功后会获得一个令牌。之后用户可在需要身份认证的请求中带上该凭证,访问对应的资源。

声明路由中间件

首先,按照 Gin 的规范编写一个中间件函数,代码如下:

提示

这里我们假设用户将访问凭证放在请求头的 "Authorization" 字段中。

main.go
package main

import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/constants"
"github.com/keepchen/go-sail/v3/sail"
)

...

// ValidateToken 校验用户令牌
func ValidateToken() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Request.Header.Get("Authorization")
if token != "this-is-a-valid-token" {
sail.Response(c).Wrap(constants.ErrAuthorizationTokenInvalid, nil).Send()
return
}

c.Next()
}
}

...

在路由中使用中间件

之后,我们可以将需要认证的路由包裹起来,统一使用相同的鉴权逻辑。

main.go
package main

import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
)
var (
...

registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
var loginRequest LoginRequest
c.ShouldBind(&loginRequest)

if loginRequest.Username != "go-sail" || loginRequest.Password != "password" {
sail.Response(c).Failure("login failed, username or password not match!")
return
}

token := "this-is-a-valid-token"
sail.Response(c).Data(token)
})
userGroup := ginEngine.Group("/user").Use(ValidateToken())
{
userGroup.GET("/balance", ...).
GET("/info", ...).
GET("/logout", ...)
}
}
...
)

高亮代码部分表示,访问 /user/balance/user/info/user/logout 这些路由时需要经过鉴权。