为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中的 HTTP 请求验证中间件

Go 中的 HTTP 请求验证中间件

Go
函数式编程 2023-03-07 17:26:57
我正在尝试创建一个通用的 HTTP 请求验证器中间件函数,该函数接受类型(可能是 reflect.Type)作为参数,然后使用该包github.com/go-playground/validator/v10将 JSON 解组为上述类型的结构并验证该结构。我试图用下面的示例代码来解释......例子type LoginRequestBody struct {   Username string `json:"username",validate:"required"`   Password string `json:"password",validate:"required"`}type SignupReqBody struct {   Username string `json:"username",validate:"required"`   Password string `json:"password",validate:"required"`   Age      int    `json:"age",validate:"required"`}// sample routers with a common middleware validator functionrouter.POST("/login", ReqValidate("LoginRequestBody"), LoginController)router.POST("/signup", ReqValidate("SignupReqBody"), SignupController)func ReqValidate(<something>) gin.HandlerFunc {   return func (c *gin.Context) {      // unmarshalling JSON into a struct      // common validation logic...      c.Next()   }}总的来说,我想使用 Joi 包实现与 Node.js 中相同的验证器灵活性。
查看完整描述

2 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

我不知道是否有必要使用中间件,但我最近尝试做一些事情,我发现了一个很棒的教程,您可以在此处查看。


使用 Gin 您可以使用绑定:


例子:


package main

import (

  "github.com/gin-gonic/gin"

  "net/http"

)

type AnyStruct struct {

   Price uint `json:"price" binding:"required,gte=10,lte=1000"`

}

func main() {

  engine:=gin.New()

  engine.POST("/test", func(context *gin.Context) {

     body:=AnyStruct{}

     if err:=context.ShouldBindJSON(&body);err!=nil{

        context.AbortWithStatusJSON(http.StatusBadRequest,

        gin.H{

            "error": "VALIDATEERR-1",

            "message": "Invalid inputs. Please check your inputs"})

        return

     }

     context.JSON(http.StatusAccepted,&body)

  })

  engine.Run(":3000")

}


查看完整回答
反对 回复 2023-03-07
?
郎朗坤

TA贡献1921条经验 获得超9个赞

不要使用逗号分隔结构标签键值对,使用空格。


您可以使用泛型(类型参数)来替换<something>,但您的控制器需要将具体类型作为它们的参数。


例如:


func ReqValidate[T any](next func(*gin.Context, *T)) gin.HandlerFunc {

    return func(c *gin.Context) {

        params := new(T)

        if err := c.ShouldBindJSON(params); err != nil {

            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

            return

        }

        next(c, params)

    }

}

然后是控制器:


type LoginRequestBody struct {

    Username string `json:"username" validate:"required"`

    Password string `json:"password" validate:"required"`

}


func LoginController(c *gin.Context, params *LoginRequestBody) {

    // ...

}


type SignupReqBody struct {

    Username string `json:"username" validate:"required"`

    Password string `json:"password" validate:"required"`

    Age      int    `json:"age" validate:"required"`

}


func SignupController(c *gin.Context, params *SignupReqBody) {

    // ...

}

然后是路由:


router := gin.Default()

router.POST("/login", ReqValidate(LoginController))

router.POST("/signup", ReqValidate(SignupController))


查看完整回答
反对 回复 2023-03-07
  • 2 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信