ホームページ > バックエンド開発 > Golang > ginvalidator を使用して Go での Jin 入力検証を簡素化する

ginvalidator を使用して Go での Jin 入力検証を簡素化する

Linda Hamilton
リリース: 2024-12-01 11:52:11
オリジナル
896 人が閲覧しました

Simplify Gin Input Validation in Go with ginvalidator

概要

ginvalidator は、私の他のオープンソース パッケージ validatorgo が提供するバリデーターとサニタイザーの広範なコレクションをラップする、Gin ミドルウェアのセットです。また、JSON フィールド構文に人気のオープンソース パッケージ gjson を使用し、JSON オブジェクトからのデータの効率的なクエリと抽出を提供します。

Gin リクエストを検証してサニタイズできるように、これらをさまざまな方法で組み合わせることができ、リクエストが有効かどうか、バリデータに従ってどのデータが一致したかを判断するツールを提供します。

人気のある js/express ライブラリの Express-validator に基づいています

サポート

このバージョンの ginvalidator では、アプリケーションが Go 1.16 で実行されている必要があります。
また、Gin 1.x.x で動作することも確認されています。

理論的根拠

なぜ使用しないのでしょうか?

  • 手書きバリデータ: 独自の検証ロジックを手動で作成することもできますが、繰り返しが多くなり、すぐに面倒になってしまいます。新しい検証が必要になるたびに、同じ種類のコードを何度も書くことになります。間違いを犯しやすく、それを維持するのは大変です。
  • Gin の組み込みモデルのバインディングと検証: Gin には検証機能が組み込まれていますが、すべての人にとって理想的なわけではありません。構造体タグには制限があり、特に複雑なルールが必要な場合、コードが読みにくくなります。さらに、検証はモデルに強く結びつきすぎるため、柔軟性があまり良くありません。
  • その他のライブラリ (Galidator など): 他にもライブラリはありますが、機能に対して複雑すぎると感じることがよくあります。特に検証のためのシンプルで単純なソリューションが必要な場合は、予想以上に多くのセットアップと作業が必要です。

インストール

マシンに Go がインストールされていることを確認してください。

ステップ 1: 新しい Go モジュールを作成する

  1. 任意の名前で空のフォルダーを作成します。
  2. ターミナルを開き、そのフォルダーに移動 (cd) し、新しい Go モジュールを初期化します。
go mod init example.com/learning
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ステップ 2: 必要なパッケージをインストールする

go get を使用して、必要なパッケージをインストールします。

  1. ジンをインストールします:
go get -u github.com/gin-gonic/gin
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. ginvalidator をインストールします。
go get -u github.com/bube054/ginvalidator
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

はじめる

何かを学ぶための最良の方法の 1 つは、例を見ることです。それでは、袖をまくってコーディングを始めましょう。

設定

最初に必要なのは、Gin サーバーを実行することです。誰かに挨拶するものを実装してみましょう。このためには、main.go を作成し、次のコードを追加します:

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.GET("/hello", func(ctx *gin.Context) {
        person := ctx.Query("person")
        ctx.String(http.StatusOK, "Hello, %s!", person)
    })

    r.Run() // listen and serve on 0.0.0.0:8080
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ターミナルで go run main.go を実行して、このファイルを実行します。

go mod init example.com/learning
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

HTTP サーバーが実行されているはずです。http://localhost:8080/hello?person=John を開いて、John に挨拶できます。

? ヒント:
Go および Gin で Air を使用してライブ リロードを実装できます。ファイルが変更されるたびにサーバーが自動的に再起動されるため、自分でこれを行う必要はありません!

バリデーターの追加

サーバーは動作していますが、問題があります。最も注目すべきは、名前が設定されていない人に挨拶したくないということです。
たとえば、http://localhost:8080/hello にアクセスすると、「Hello, 」と表示されます。

そこで ginvalidator が役に立ちます。リクエストを検証するために使用されるバリデーター、サニタイザー、およびモディファイアーを提供します。
個人のクエリ文字列が空であってはいけないことをチェックするバリデーターと修飾子を追加しましょう。バリデーターの名前は Empty 、修飾子の名前は Not:
です。

go get -u github.com/gin-gonic/gin
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

? 注:

簡潔にするために、コード例では gv が ginvalidator のエイリアスとして使用されています。

次に、サーバーを再起動し、再度 http://localhost:8080/hello にアクセスします。うーん、まだ「Hello, !」と表示されます...なぜですか?

検証エラーの処理

ginvalidator 検証チェーンは、検証エラーをユーザーに自動的に報告しません。
その理由は簡単です。バリデーターを追加したり、フィールドを追加したりするときに、どのようにエラーを収集する必要があるでしょうか。すべてのエラーのリスト (フィールドごとに 1 つだけ、全体で 1 つだけ) が必要ですか...?

次の明らかなステップは、上記のコードを再度変更し、今回は ValidationResult 関数を使用して検証結果を検証することです。

go get -u github.com/bube054/ginvalidator
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、http://localhost:8080/hello に再度アクセスすると、わかりやすくするためにフォーマットされた次の JSON コンテンツが表示されます。

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.GET("/hello", func(ctx *gin.Context) {
        person := ctx.Query("person")
        ctx.String(http.StatusOK, "Hello, %s!", person)
    })

    r.Run() // listen and serve on 0.0.0.0:8080
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

さて、これが私たちに伝えていることは、

  • このリクエストには 1 つだけエラーがありました;
  • このフィールドは person と呼ばれます;
  • クエリ文字列内にあります (場所: "queries");
  • 表示されたエラー メッセージは「無効な値」でした。

これはより良いシナリオですが、まだ改善の余地があります。続けてみましょう。

より適切なエラー メッセージの作成

すべてのリクエスト位置バリデータは、オプションの 2 番目の引数を受け入れます。これは、エラー メッセージのフォーマットに使用される関数です。 nil が指定された場合、上記の例に示すように、デフォルトの汎用エラー メッセージが使用されます。

go run main.go
ログイン後にコピー
ログイン後にコピー

ここで http://localhost:8080/hello に再度アクセスすると、次の JSON コンテンツと新しいエラー メッセージが表示されます。

package main

import (
    "net/http"

    gv "github.com/bube054/ginvalidator"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.GET("/hello", gv.NewQuery("person", nil).
        Chain().
        Not().
        Empty(nil).
        Validate(), func(ctx *gin.Context) {
            person := ctx.Query("person")
            ctx.String(http.StatusOK, "Hello, %s!", person)
        })

    r.Run()
}
ログイン後にコピー
ログイン後にコピー

検証/サニタイズされたデータへのアクセス

GetMatchedData を使用すると、ginvalidator が検証および/またはサニタイズしたすべてのデータが自動的に収集されます。このデータは、MatchedData:
の Get メソッドを使用してアクセスできます。

go mod init example.com/learning
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

http://localhost:8080/hello?person=John を開いて、ジョンに敬意を表します!

使用可能な場所は、BodyLocation、CookieLocation、QueryLocation、ParamLocation、および HeaderLocation です。
これらの各場所には、検証/サニタイズされたデータが保存されている場所を返す String メソッドが含まれています。

入力のサニタイズ

ユーザーは空の人名を送信できなくなりましたが、HTML をページに挿入することはできます。これは、クロスサイト スクリプティングの脆弱性 (XSS) として知られています。
どのように機能するかを見てみましょう。 http://localhost:8080/hello?person=John にアクセスすると、「こんにちは、ジョン!」と表示されるはずです。
この例は問題ありませんが、攻撃者は人物のクエリ文字列を

著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート