如何验证来自中间件 go-gin 的数据
How to validate data from a middleware go-gin
尝试学习 golang,但我迷失了在验证中间件中使用 context.Request.Body
及其 struct
简要说明它们是如何相互连接的,在此先感谢您的帮助
我的中间件
package validations
import (
"github.com/bihire/ikaze_server_app/entity"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
func SignupValidator(c *gin.Context) {
// user := c.Request.Body
var user entity.User
validate := validator.New()
if err := validate.Struct(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
}
我的结构
package entity
type User struct {
Username string `json:"username" validate:"required"`
Email string `json:"email" validate:"email"`
Password string `json:"password" validate:"min=8,max=32,alphanum"`
ConfirmPassword string `json:"confirm_password" validate:"eqfield=Password,required"`
}
返回响应错误
{
"error": "Key: 'User.Username' Error:Field validation for 'Username' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag\nKey: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag\nKey: 'User.ConfirmPassword' Error:Field validation for 'ConfirmPassword' failed on the 'required' tag"
}{
"username": "bihire",
"email": "hgh@gmail.com",
"password": "password",
"confirm_password": "password"
}
带中间件的路由器
auth.POST("login", gin.Logger(), validations.SignupValidator, func(ctx *gin.Context) {
ctx.JSON(200, videoController.Save(ctx))
})
您似乎错过了 return
:
func SignupValidator(c *gin.Context) gin.HandlerFunc {
return func(c *gin.Context) {
var user entity.User
if err := c.ShouldBindJSON(&user); err == nil {
validate := validator.New()
if err := validate.Struct(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
c.Abort()
return
}
}
c.Next()
}
}
请注意,如果验证失败,我们会调用 c.Abort()
。这是因为即使在你使用 c.Next()
.
编写 header (c.JSON()
) 之后,gin 也会调用链中的下一个函数
尝试学习 golang,但我迷失了在验证中间件中使用 context.Request.Body
及其 struct
简要说明它们是如何相互连接的,在此先感谢您的帮助
我的中间件
package validations
import (
"github.com/bihire/ikaze_server_app/entity"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
func SignupValidator(c *gin.Context) {
// user := c.Request.Body
var user entity.User
validate := validator.New()
if err := validate.Struct(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
}
我的结构
package entity
type User struct {
Username string `json:"username" validate:"required"`
Email string `json:"email" validate:"email"`
Password string `json:"password" validate:"min=8,max=32,alphanum"`
ConfirmPassword string `json:"confirm_password" validate:"eqfield=Password,required"`
}
返回响应错误
{
"error": "Key: 'User.Username' Error:Field validation for 'Username' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag\nKey: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag\nKey: 'User.ConfirmPassword' Error:Field validation for 'ConfirmPassword' failed on the 'required' tag"
}{
"username": "bihire",
"email": "hgh@gmail.com",
"password": "password",
"confirm_password": "password"
}
带中间件的路由器
auth.POST("login", gin.Logger(), validations.SignupValidator, func(ctx *gin.Context) {
ctx.JSON(200, videoController.Save(ctx))
})
您似乎错过了 return
:
func SignupValidator(c *gin.Context) gin.HandlerFunc {
return func(c *gin.Context) {
var user entity.User
if err := c.ShouldBindJSON(&user); err == nil {
validate := validator.New()
if err := validate.Struct(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
c.Abort()
return
}
}
c.Next()
}
}
请注意,如果验证失败,我们会调用 c.Abort()
。这是因为即使在你使用 c.Next()
.
c.JSON()
) 之后,gin 也会调用链中的下一个函数