Gin 框架小知识 | 青训营

194 阅读4分钟

设置路由小知识

gin.IRoutes 和 gin.IRouter 有什么区别

在 Gin 框架中,gin.IRoutesgin.IRouter 都是接口类型,用于定义路由组(Router Group)的方法。

  1. gin.IRoutes 接口:

    • gin.IRoutes 接口定义了用于添加路由处理函数的方法,例如 GETPOSTPUTDELETE 等。
    • 它包含了常见的 HTTP 请求方法,如 GET()POST()PUT()DELETE() 等,可以通过这些方法添加路由及其对应的处理函数。
    • gin.IRoutes 接口还继承了 gin.IRouter 接口,因此可以使用 gin.IRouter 接口中定义的方法。
  2. gin.IRouter 接口:

    • gin.IRouter 接口定义了用于路由组管理和中间件的方法。
    • 它包含了一些用于路由组管理的方法,如 Group()(创建子路由组)、Use()(添加中间件)、Handle()(处理请求)、Any()(匹配任意请求方法)等。
    • gin.IRouter 接口还定义了一些其他的方法,如 Static()(静态文件服务)、HandleContext()(处理请求上下文)、Routes()(获取所有路由信息)等。

总结来说,gin.IRoutes 接口是 gin.IRouter 接口的子集,它主要用于添加路由处理函数的方法。而 gin.IRouter 接口提供了更多的方法,用于路由组管理、中间件的添加和其他路由相关的操作。

在实际使用中,通常使用 *gin.RouterGroup 类型作为路由组,它实现了 gin.IRoutesgin.IRouter 接口,因此可以直接使用 *gin.RouterGroup 对象进行路由的管理和处理。

通过中间件实现路由身份验证

在 Gin 框架中,通过中间件进行路由身份验证属于处理请求的中间层,而不是严格意义上的处理器(handler)层。

在典型的三层架构中,处理器层(handler layer)负责处理请求和生成响应,一般包含了路由定义和具体的处理函数。而中间件层(middleware layer)则位于处理器层和底层服务(如数据库、缓存等)之间,用于处理请求和响应的前置和后置逻辑,例如身份验证、日志记录、错误处理等。

在 Gin 框架中,路由定义和处理函数一般位于处理器层(handler layer),而通过中间件进行的身份验证逻辑则属于中间件层(middleware layer)。中间件可以在请求到达处理器之前对请求进行预处理,例如验证请求的身份、检查权限等,从而增加了代码的可重用性和可维护性。

实现的路由身份验证逻辑属于中间件层,用于在请求到达处理函数之前进行身份验证。处理函数属于处理器层,负责具体的业务逻辑处理。

通过中间件实现的路由身份验证属于中间件层,而不是严格意义上的处理器层。

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.Query("token")
		if token == "" {
			c.JSON(http.StatusUnauthorized, response.ErrorMessage{
				Response: response.Response{
					StatusMsg:  "unauthorized",
					StatusCode: 1,
				},
			})
			return
		}

		_, e := c.Get("userId")
		if e {
			c.Next()
			return
		}
		claims, err := jwt.ParseToken(token)
		if err != nil {
			log.Printf("AuthMiddleware|token解析错误|%v", err)
			c.JSON(http.StatusUnauthorized, response.ErrorMessage{
				Response: response.Response{
					StatusMsg:  "unauthorized",
					StatusCode: 1,
				},
			})
			return
		}
		userID := claims.UserID
		c.Set("userId", userID)
		c.Next()
		return
	}
}
  1. AuthMiddleware 函数返回一个 gin.HandlerFunc 类型的函数,该函数充当中间件处理函数。
  2. 在中间件处理函数中,首先获取请求中的 token 参数。如果 token 为空,表示未提供身份验证令牌,中间件将返回一个包含未经授权错误信息的 JSON 响应,并设置状态码为 http.StatusUnauthorized
  3. 如果请求中存在 token 参数,接下来会检查是否已经在请求上下文中设置了 userId。如果已经设置,说明已经经过身份验证,中间件将继续处理下一个请求。
  4. 如果 userId 未设置,则解析提供的 token 并验证其有效性。如果解析和验证过程中出现错误,中间件将返回一个包含未经授权错误信息的 JSON 响应,并设置状态码为 http.StatusUnauthorized
  5. 如果 token 解析成功,从解析结果中获取 userID,并将其设置到请求上下文中的 userId 键中,以便后续处理函数使用。
  6. 最后,中间件调用 c.Next() 继续处理下一个请求。

综上所述,该中间件函数用于对请求进行身份验证,要求请求中提供有效的 token 参数,并在验证通过后将用户 ID 设置到请求上下文中,以便后续处理函数使用。如果身份验证失败或未提供有效的 token 参数,将返回相应的错误响应。

状态码

http.StatusUnauthorizedhttp.StatusUnauthorized 是一个常量,表示 HTTP 响应状态码 401 Unauthorized。它表示客户端请求未经授权,需要进行身份验证才能访问所请求的资源。

在你提供的代码中,当身份验证中间件检测到请求未提供有效的身份验证令牌或身份验证失败时,使用 http.StatusUnauthorized 作为响应的状态码。这样的响应状态码会告知客户端请求未经授权,需要提供有效的凭证才能继续访问。在返回的 JSON 响应中,也会包含相应的错误信息,提示客户端请求未经授权。

使用正确的状态码能够遵循 HTTP 协议,并帮助客户端和服务器之间进行适当的通信。http.StatusUnauthorized 用于表示身份验证失败的情况,可以帮助客户端了解需要提供有效凭证以继续请求的资源。