🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
中间件提供了一种方便的机制来过滤进入应用程序的 HTTP 请求。例如,`GoHub` 包含一个验证用户身份的中间件。 如果用户未能通过认证,中间件会把用户重定向到登录页面。 反之,用户如果通过验证, 中间件将把请求进一步转发到应用程序中。 当然,除了验证身份外,还可以编写其他的中间件来执行各种任务。例如:`CORS` 中间件可以负责为所有的应用返回的 `responses` 添加合适的响应头。日志中间件可以记录所有传入应用的请求。 `GoHub` 自带了一些中间件,包括身份验证、限流器 、HTTP请求日志等。所有的这些中间件都位于`app/http/middlewares`目录。 ## 定义中间件 我们来自己定义一个`JWT`鉴权的中间件 ``` // Package middlewares Gin 中间件 package middlewares import ( "github.com/spf13/cast" "gohub/app/models/user" "gohub/pkg/jwt" "gohub/pkg/response" "net/http" "github.com/gin-gonic/gin" ) // AuthJWT 验证用户身份 func AuthJWT() gin.HandlerFunc { return func(c *gin.Context) { // 从标头 Authorization:Bearer xxxxx 中获取信息,并验证 JWT 的准确性 claims, err := jwt.NewJWT().ParserToken(c) // JWT 解析失败,有错误发生 if err != nil { response.ShowError(c, http.StatusUnauthorized, err.Error()) c.Abort() return } // JWT 解析成功,设置用户信息 userModel := user.Get(cast.ToString(claims.UserID)) if userModel.ID == 0 { response.ShowError(c, http.StatusUnauthorized, "用户不存在") c.Abort() return } // 将用户信息存入 gin.context 里,后续 auth 包将从这里拿到当前用户数据 c.Set("user_id", userModel.GetStringID()) c.Set("user_name", userModel.Name) c.Set("user", userModel) c.Next() } } ``` ***** ### 在路由使用中间件 ``` userRouter.GET("/profile/", middlewares.AuthJWT(), handler.UserProfile) userRouter.POST("/update", middlewares.AuthJWT(), handler.UpdateUserProfile) ``` ***** ### 在路由组使用中间件 ``` // 所有的 v1 版本的路由都将存放到这里 v1 := r.Group("/v1") // 全局限流中间件:每小时限流。这里是所有 API (根据 IP)请求加起来。 v1.Use(middlewares.AuthJWT()) { v1.GET("/profile/", handler.UserProfile) } ``` ## 全局中间件 如果你希望中间件在应用处理每个`HTTP`请求期间运行,只需要在 `bootstrap/route.go`中的`registerGlobalMiddleWare`方法添加这个中间件即可,例如: ``` // 全局中间件 func registerGlobalMiddleWare(router *gin.Engine) { router.Use( // 记录HTTP日志 middlewares.Logger(), // 全局异常处理 middlewares.Recovery(), // 强制 User Agent 中间件 middlewares.ForceUA(), ) } ```