2

gin フレームワークを使用して、go でバリデーター/バインダー ミドルウェアを作成しようとしています。

これがモデルです

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}

ルーター

router.POST("/login",middlewares.Validator(LoginForm{}) ,controllers.Login)

ミドルウェア

func Validator(v interface{}) gin.HandlerFunc{
    return func(c *gin.Context){
        a := reflect.New(reflect.TypeOf(v))
        err:=c.Bind(&a)
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

私はgolangが初めてです。問題は、間違った変数へのバインドにあることを理解しています。これを解決する他の方法はありますか?

4

1 に答える 1

0

私のコメントを明確にし、

func Validator(v interface{}) gin.HandlerFuncMWの署名を使用する代わりに、func Validator(f Viewfactory) gin.HandlerFunc

ViewFactory次のような関数タイプの場合type ViewFactory func() interface{}

MWは変更できるので

type ViewFactory func() interface{}

func Validator(f ViewFactory) gin.HandlerFunc{
    return func(c *gin.Context){
        a := f()
        err:=c.Bind(a) // I don t think you need to send by ref here, to check by yourself
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

このようにルーターを書くことができます

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}
func NewLoginForm() interface{} {
   return &LoginForm{}
}
router.POST("/login",middlewares.Validator(NewLoginForm) ,controllers.Login)

さらに先に進むと、後でこれについて調べる必要があると思います。値を取得したら、このようinterface{}に戻すことができます。LoginFormv := some.(*LoginForm)

または、セキュリティを強化するためにこのようにします

if v, ok := some.(*LoginForm); ok {
 // v is a *LoginForm
}

詳細については、golang 型アサーションを参照してください。

于 2016-10-31T19:37:29.113 に答える