-
请求处理前的预处理
-
中间件可以在请求到达实际的业务处理逻辑之前,对请求进行预处理。例如,进行身份验证。
-
以下是一个简单的身份验证中间件示例:
-
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
c.Abort()
return
}
// 在这里可以进行更复杂的token验证,比如解析JWT等
c.Next()
}
}
-
在这个中间件中,它检查请求头中的
Authorization字段是否存在。如果不存在,就直接返回401 Unauthorized状态码,并且中断请求的后续处理(通过c.Abort())。如果存在,可以进行进一步的验证,验证通过后调用c.Next(),让请求继续传递到下一个中间件或者业务处理函数。
-
记录请求信息(日志记录)
- 就像前面定义日志中间件的示例一样,中间件可以用于记录请求的详细信息,如请求方法、路径、请求时间、响应状态码等。
- 这种日志记录对于调试应用程序、监控系统性能以及安全审计都非常重要。例如,通过分析日志可以发现哪些接口被频繁访问,哪些接口出现了大量错误等。
-
响应处理后的操作
-
中间件也可以在响应返回给客户端之后进行一些操作。比如,在响应头中添加一些公共的信息。
-
示例代码如下:
-
func AddResponseHeaderMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
c.Writer.Header().Set("X - Powered - By", "My Awesome Server")
}
}
-
这个中间件先让请求正常处理(
c.Next()),在响应返回给客户端之前,在响应头中添加了一个X - Powered - By字段,用于标识服务器信息。
-
错误处理和恢复
- 中间件可以用于捕获业务处理过程中可能出现的 panic(恐慌),并进行合理的恢复。
- 示例如下:
func RecoveryMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err!= nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
}
}()
c.Next()
}
}
-
在这个中间件中,通过
defer关键字定义了一个延迟执行的函数。当业务处理函数(或者其他中间件)中发生panic时,就会触发这个延迟函数,在这里可以捕获panic并返回一个合适的错误响应(如500 Internal Server Error),而不是让整个应用程序崩溃。
-
功能扩展和复用
- 中间件可以将一些通用的功能封装起来,方便在多个不同的路由或者应用中复用。例如,跨域资源共享(CORS)中间件。
- 以下是一个简单的 CORS 中间件示例:
func CorsMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access - Control - Allow - Origin", "*")
c.Writer.Header().Set("Access - Control - Allow - Methods", "POST, GET, OPTIONS, PUT, DELETE")
c.Writer.Header().Set("Access - Control - Allow - Headers", "Content - Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.JSON(http.StatusOK, gin.H{"message": "Options Request"})
c.Abort()
return
}
c.Next()
}
}
- 这个中间件用于设置 CORS 相关的响应头,允许来自任何源的请求(在实际应用中可能需要更严格的配置),指定允许的请求方法和请求头。对于
OPTIONS请求,直接返回一个响应并中断后续处理,因为浏览器在跨域请求时会先发送OPTIONS预检请求。通过使用中间件,可以方便地将这些功能添加到整个应用或者特定的路由组中。