データ検証は、Webアプリケーションの重要なコンポーネントです。セキュリティの脆弱性、データの破損、およびユーザー入力を使用するときに発生する可能性のあるさまざまな問題を防ぐのに役立ちます。
この記事では、データ検証とは何か、なぜそれが非常に重要なのかを調べます。クライアント側の検証をサーバー側の検証と比較し、クライアント側の検証を依存すべきではない理由を説明します。
次に、Laravelアプリケーションで一般的に使用する便利な検証ルールを紹介します。最後に、独自の検証ルールを作成する方法を学び、それらをテストして、それらが期待どおりに機能することを確認します。
データ検証は、データを使用しようとする前にデータの有効性をチェックするプロセスです。これは、たとえば、要求に必要なフィールドが存在するかどうか、またはフィールドが特定のパターンと一致するかどうか、またはデータベースでユニークであるかなど、より複雑なチェックをチェックする簡単なアイテムです。
通常、Webアプリケーションでデータを検証する場合、データが無効な場合は、ユーザーにエラーメッセージを返す必要があります。
これは、セキュリティの脆弱性、データの破損を防ぎ、データの精度を向上させるのに役立ちます。したがって、データが有効である場合にのみ、リクエストを処理し続けます。
覚えておいてください、ユーザーからのデータを信頼することはできません(少なくとも確認する前に!)。
データ検証が重要である理由は、以下を含む多くの理由があります。
#セキュリティを改善#誤ったデータストレージを防止
別の例を挙げると、ユーザーが投票に投票できるWebアプリケーションを構築しているとします。投票は、
時間とAppModelsPoll
モデルで指定された時間の間にのみ投票できます。投票を設定するときにopens_at
時間の前に誰かが誤って設定するとどうなりますか?アプリでこれをどのように処理するかによって、これはさまざまな問題を引き起こす可能性があります。 closes_at
closes_at
モデルに保存する前にデータを検証することにより、アプリケーションのデータ精度を改善し、誤ったデータが保存される可能性を減らすことができます。 opens_at
HTTPリクエストで渡されたデータを確認できることに加えて、職人コマンドを確認することもできます。これにより、開発者は誤って無効な値を入力し、アプリケーションに問題を引き起こすことができなくなります。
クライアント検証は、データをサーバーに送信する前にブラウザで実行される検証です。 JavaScriptまたはHTML属性を使用して実装できます。
たとえば、HTMLの数字フィールドに簡単な検証を追加して、ユーザーが入力した番号が1〜10であることを確認できます。
<input type="number" min="1" max="10" required>
type="number"
min="1"
max="10"
required
ほとんどのブラウザでは、ユーザーが無効な値(またはまったく値なし)でフォームを送信しようとする場合、ブラウザはフォームの送信をブロックし、ユーザーにエラーメッセージまたはプロンプトを表示します。 誰かがブラウザで開発者ツールを開いた場合、設定したクライアントの確認を簡単に削除してバイパスできます。
さらに、悪意のあるユーザーがアプリを攻撃しようとする場合、通常、自動化されたスクリプトを使用してリクエストをサーバーに直接送信することを覚えておくことが重要です。これは、設定したクライアントの検証がバイパスされることを意味します。
#サーバー側の検証
サーバー側の検証は、サーバー上のアプリケーションバックエンドで実行される検証です。 Laravelアプリケーションのコンテキストでは、これは通常、コントローラーまたはフォームリクエストクラスで実行される検証です。
Laravelが確認をどのように処理するか
これで、検証とは何か、なぜそれが重要なのかを理解したので、Laravelでそれを使用する方法を見てみましょう。
しばらくLaravelを使用している場合、Laravelにはフレームワークに組み込まれた驚くべき検証システムがあることがわかります。したがって、アプリの検証を開始するのは非常に簡単です。
ファサードを使用してIlluminateSupportFacadesValidator
メソッドを呼び出すことができます。 make
メソッドに渡すことができます。
make
data
rules
make
。これらを使用して、ユーザーに返されるエラーメッセージをカスタマイズできますが、この記事では説明しません。 messages
attributes
2つのフィールドを検証する可能性のある例を見てみましょう。
上記の例では、2つのフィールドを検証していることがわかります:と
。これらの2つのフィールドの値をハードコードして、例をより明確にしますが、実際のプロジェクトでは、通常、これらのフィールドをリクエストから取得します。<input type="number" min="1" max="10" required>
フィールドが設定されており、文字列であり、最大250文字の長さがあるかどうかを確認します。 title
body
検証装置を作成した後、返されたtitle
インスタンスのメソッドを呼び出すことができます。たとえば、検証が失敗したかどうかを確認するには、description
メソッドを呼び出すこともできます:IlluminateValidationValidator
fails
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
を上げます。 Laravelは、作成された要求のタイプに基づいてこの例外を自動的に処理します(アプリのデフォルトの例外処理を変更しなかったと仮定します)。リクエストがWebリクエストの場合、Laravelはセッションでエラーを使用して、ユーザーを前のページにリダイレクトして表示します。リクエストがAPIリクエストの場合、Laravelは次のように検証エラーのJSON表現を含むAvalidate
応答を返します。
$validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] ); if ($validator->fails()) { // 一个或多个字段验证失败。 // 在此处进行处理... }
validate
Laravelアプリケーションでデータを検証するもう1つの一般的な方法は、フォームリクエストクラスを使用することです。フォームリクエストクラスは、拡張機能IlluminateValidationValidationException
を備えたクラスです。これは、承認チェックと着信リクエストの検証を実行するために使用されます。 422 Unprocessable Entity
Laravelは、コントローラーメソッドのコードを実行する前にリクエストで渡されたデータの検証を自動的に実行するため、コントローラーメソッドを整頓するための優れた方法であると思います。したがって、Validatorインスタンスで自分自身でメソッドを実行することを忘れないでください。
Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] )->validate();
<input type="number" min="1" max="10" required>
コントローラーメソッドでは、メソッドパラメーターとしてAppHttpRequestsUsersStoreUserRequest
フォームリクエストクラス(後で導入します)を受け入れることがわかります。これは、Laravelに、このメソッドがHTTPリクエストを介して呼び出されたときに、このリクエストクラスで確認を自動的に実行することを示します。
次に、コントローラーメソッドのリクエストインスタンスのvalidated
メソッドを使用して、リクエストから確認されたデータを取得します。これは、検証済みのデータのみを返すことを意味します。たとえば、コントローラー内の新しいprofile_picture
フィールドを保存しようとする場合は、フォームリクエストクラスにも追加する必要があります。それ以外の場合は、validated
メソッドはそれを返さないので、$request->validated('profile_picture')
はnull
を返します。
AppHttpRequestsUsersStoreUserRequest
フォームリクエストクラスを見てみましょう:
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
リクエストクラスには2つの方法が含まれていることがわかります。
authorize
を返す場合、a false
応答がユーザーに返されます。メソッドが403 Forbidden
を返す場合、検証ルールが実行されます。 true
rules
フィールドを設定し、電子メールでなければならないことを指定し、rules
テーブル(name
列)で一意でなければなりません。最後に、users
ご覧のとおり、これは検証ロジックをコントローラーロジックから分離する素晴らしい方法であり、コードの読みやメンテナンスが容易になることがわかりました。 email
password
一般的に使用される検証ルールは、laravel
私がすでに述べたように、Laravel検証システムは非常に強力であり、アプリに検証を簡単に追加できます。
実行する必要がある一般的なタイプの検証は、検証配列です。これは、渡されたIDアレイがすべて有効かどうかの確認から、検証リクエストで渡されたオブジェクト配列に特定のフィールドがあるかどうかを確認することになります。
配列の検証方法の例を見てみましょう。次に、実行中のことについて説明します。
<input type="number" min="1" max="10" required>
name
検証のために、最初にemail
フィールドが設定され、配列であることを定義します。次に、アレイの各アイテム(
およびusers
フィールドを含む配列であることを指定します。 users.*
name
次に、email
フィールド(
フィールド(name
方向を使用)を設定し、電子メールでなければならないことを指定し、users.*.name
列で一意でなければなりません。 email
users.*.email
検証ルールでusers
ワイルドカードを使用できるようにすることにより、アプリケーションのデータ配列を簡単に確認できます。 email
*
Laravelは、使用できる便利な日付検証ルールを提供します。まず、フィールドが有効な日付であることを確認するには、
ルールを使用できます。
date
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
フィールドが含まれていると仮定し、date_format
が今日より遅れているか
$validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] ); if ($validator->fails()) { // 一个或多个字段验证失败。 // 在此处进行处理... }
を使用できます
opens_at
上記の例では、closes_at
フィールドのルールのパラメーターとしてcloses_at
を渡したことがわかります。 Laravelは、この文字列をopens_at
オブジェクトに変換し、そのオブジェクトと比較しようとします。 after
Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] )->validate();
ルールに合格します。 Laravelは、これが検証されている別のフィールドであることを自動的に検出し、2つのフィールドを互いに比較します。 today
同様に、laravelは、日付が別の日付よりも早いかどうかを確認するために使用できるopens_at
およびafter
ルールも提供します。
strtotime
DateTime
#パスワードを確認
Web開発者として、私たちの仕事は、ユーザーがオンラインで安全に役立つことです。これを行う方法の1つは、パスワードを特定の長さであること、特定の文字を含めるなど、アプリケーションで適切なパスワードプラクティスを宣伝することです。 closes_at
opens_at
Laravelは、パスワードを確認するために使用できるクラスを提供することにより、作業を簡素化します。 after_or_equal
私たちの検証は次のようになるかもしれません:
<input type="number" min="1" max="10" required>
例に示すように、リンク可能な方法を使用して、必要なパスワード検証ルールを作成しています。しかし、これらのルールを複数の異なる場所(例:登録、リセット、アカウントページのパスワードを更新するなど)で使用し、少なくとも12文字を実施するためにこの検証を変更するとどうなりますか?これらのルールが使用されているすべてのものを反復し、それらを更新する必要があります。
これを簡素化するために、Laravelを使用すると、アプリケーション全体で使用できるパスワード検証ルールのデフォルトセットを定義できます。このようなメソッドを使用して、一連のデフォルトルールを定義できます。
AppProvidersAppServiceProvider
これを行うと、検証ルールでboot
を呼び出して、Password::defaults()
で指定したルールを使用できます。
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
Password::defaults()
私が取り組んだほぼすべてのプロジェクトには、何らかの形のカラーピッカーが含まれています。プロフィールの色を選択するユーザー、ページの一部の背景色、またはその他のコンテンツであろうと、それは一般的なコンテンツです。 AppServiceProvider
$validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] ); if ($validator->fails()) { // 一个或多个字段验证失败。 // 在此处进行处理... }
サーバーを介してファイルをアプリにアップロードする場合、保存しようとする前にファイルが有効であることを確認する必要があります。ご想像のとおり、Laravelは使用できるファイル検証ルールを提供します。
#FF00FF
ユーザーがPDF(.pdf)またはMicrosoft Word(.docx)ファイルをアップロードできるようにしたいとします。検証は次のようになる場合があります:hex_color
Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] )->validate();
{ "message": "The title field is required. (and 1 more error)", "errors": { "title": [ "The title field is required." ], "description": [ "The description field is required." ] } }
types
min
max
10kb
10mb
さらに、<input type="number" min="1" max="10" required>
アプリをファイルするために別のアプローチをとることをお勧めします。たとえば、ユーザーのブラウザからクラウドストレージ(S3など)に直接アップロードすることをお勧めします。これを希望する場合は、Filepondを使用してLaravelの記事で私のアップロードファイルをチェックしてください。
#データベースにフィールドが存在することを確認します
たとえば、
アプリにユーザーがいると、ルートを作成してチームに割り当てることができるとします。したがって、リクエストでは、リクエストに渡されたがuser_ids
テーブルに存在することを確認する必要がある場合があります。 users
これを行うには、
上記の例では、exists
アレイで渡された各IDが
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
user_ids
これは、使用しているデータが有効であり、使用しようとする前にデータベースに存在することを確認するための優れた方法です。 users
id
さらに一歩進めたい場合は、
ルールに適用して、実行中のクエリをさらにフィルタリングできます。
上記の例では、配列で渡された各IDがwhere
テーブルのexists
列に存在するかどうかを確認しており、ユーザーの
$validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] ); if ($validator->fails()) { // 一个或多个字段验证失败。 // 在此处进行处理... }
user_ids
#データベースのフィールドの一意性を確認しますusers
id
たとえば、is_verified
テーブルがあるとし、true
フィールドが一意であることを確認したいとします。
フィールドが設定されており、電子メールであり、exists
テーブルのunique
列で一意かどうかを確認しています。
しかし、ユーザーがメールアドレスを更新できるプロフィールページでこの検証を使用しようとするとどうなりますか?ユーザーが更新しようとした電子メールアドレスを含むusers
テーブルに行があるため、検証は失敗します。この場合、一意性をチェックするときにユーザーIDを無視するためにemail
メソッドを使用できます。
unique
Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] )->validate();
"ユーザー制御の要求入力をignore
メソッドに渡さないでください。代わりに、雄弁なモデルのインスタンスから自己侵入IDやUUIDなど、システムによって生成された一意のIDのみを渡す必要があります。
また、
メソッドに渡すことでこれを行うことができます:unique
where
where
独自の検証ルールを作成します
<input type="number" min="1" max="10" required>
カスタム検証ルールを構築する方法、使用方法、テストを作成する方法を見てみましょう。
この記事の目的のために、私たちは何を検証しているかについてあまり心配していません。カスタム検証ルールを作成する一般的な構造とそれらをテストする方法を理解したいだけです。したがって、文字列がパリンドロームかどうかを確認するための簡単なルールを作成します。
わからない場合、パリンドロームは、順方向と逆方向に同じことを読む単語、フレーズ、数字、または他の文字のシーケンスです。たとえば、「レースカー」はパリンドロームです。なぜなら、弦を反転させると、まだ「レースカー」だからです。そして、「Laravel」はパリンドロームではありません。なぜなら、弦を反転させると「レバラル」になるからです。
開始するには、プロジェクトルートで次のコマンドを実行することにより、まず新しい検証ルールを作成します。
これは、私たちのために新しい
ファイルを作成する必要があります:
use Illuminate\Support\Facades\Validator; $validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] );
メソッドを呼び出します。このメソッドは、3つのパラメーターを受け入れます
App/Rules/Palindrome.php
$validator = Validator::make( data: [ 'title' => 'Blog Post', 'description' => 'Blog post description', ], rules: [ 'title' => ['required', 'string', 'max:100'], 'description' => ['required', 'string', 'max:250'], ] ); if ($validator->fails()) { // 一个或多个字段验证失败。 // 在此处进行处理... }
validate
$attribute
:検証が失敗した場合に呼び出すことができる閉鎖。 $value
は、次のように検証ロジックを$fail
閉鎖を呼び出します。これにより、フィールドが検証に失敗します。検証が通過した場合、ルールは何も実行せず、アプリケーションを使用し続けることができます。
validate
これは、デモンストレーションのために作成した単純なルールですが、アプリケーションのためにより複雑なルールを構築する方法のアイデアが得られることを願っています。
アプリの他のコードと同様に、検証ルールをテストして、予想どおりに機能することを確認することが重要です。それ以外の場合は、期待どおりに機能しないルールを使用するリスクがあります。
これを行う方法を理解するには、前のセクションで作成したパリンドロームルールをテストする方法を見てみましょう。
この特定のルールでは、2つの状況をテストしたいと思います。
ディレクトリにtests/Unit/Rules
という名前の新しいテストファイルを作成します。 PalindromeTest.php
上記のテストファイルでは、2つのテストを定義します。
<input type="number" min="1" max="10" required>
rule_passes_with_a_valid_value
rule_fails_with_an_invalid_value
属性を使用して、テストのテストに有効な値と無効な値のリストを提供します。これは、テストをきれいに保ち、同じテストで複数の値をチェックできるようにするための素晴らしい方法です。たとえば、誰かが
テストでは、有効な値を使用して、ルール上のPHPUnitFrameworkAttributesDataProvider
メソッドを呼び出します。クロージャーをvalidValues
を追加できることがわかります。
rule_passes_with_a_valid_value
テストでは、最初のテストと同じですが、今回は無効な値をルールに渡します。閉鎖が実行された場合(つまり、検証が失敗した)、閉鎖が呼び出されると予想されるため、テストが渡されることを指定しました。閉鎖を実行せずにテストの終了に到達した場合、アサーションは実行されず、Phpunitは私たちの警告をトリガーするはずです。ただし、テストがエラーを与えるよりも明示的に失敗することを確認する場合は、テストを作成するために少し異なるアプローチを取る必要がある場合があります。 validate
fail
結論assertTrue(true)
また、Laravelアプリで使用したい便利な検証ルールも取り上げました。最後に、独自の検証ルールを作成する方法を検討し、それらをテストして、それらが期待どおりに機能することを確認します。
これで、アプリケーションのセキュリティと信頼性を向上させるために、より多くの検証を使用し始めるのに十分な自信を持つ必要があることを願っています。
以上がLaravel検証の究極のガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。