JavaScript:クライアント側とサーバー側の検証


179

クライアント側とサーバー側のどちらの検証を行う方が良いですか?

私たちの状況では、

  • jQueryおよびMVC。
  • ビューとコントローラーの間で受け渡すJSONデータ。

私が行う検証の多くは、ユーザーが入力したデータを検証することです。たとえば、このkeypressイベントを使用して、テキストボックス内の文字を防止し、最大文字数を設定します。数値は範囲内にあります。

より良い質問は、クライアント側よりもサーバー側の検証を行うことのメリットは何でしょうか?


素晴らしい答えをみんなに。私たちが持っているウェブサイトはパスワードで保護されており、小規模なユーザーベース(50未満)向けです。JavaScriptを実行していない場合は、忍者を送信します。しかし、もし私たちがすべての人のためにサイトを設計しているなら、私は両側で検証を行うことに同意します。


2
javascriptを無効にできる
Enrico Murru、

JavaScriptを無効にするユーザーをブロックする確実な方法はありません。ユーザーがJSを有効にしてページにアクセスし、次にそれを無効にした場合、あなたができることは何もありません。(OK、JSを使用して送信コントロールを実装できるため、このシナリオでは機能しなくなりますが、他のすべてと同様にバイパスできます。)
Stewart

回答:


347

他の人が言ったように、両方を実行する必要があります。理由は次のとおりです。

クライアント側

平均的なユーザーにより良いフィードバックを与えることができるため、最初にクライアント側で入力を検証する必要があります。たとえば、無効なメールアドレスを入力して次のフィールドに移動した場合、エラーメッセージをすぐに表示できます。これにより、ユーザーはフォームを送信するにすべてのフィールドを修正できます。

サーバー上でのみ検証する場合は、フォームを送信し、エラーメッセージを受け取って、問題を突き止める必要があります。

(この問題は、ユーザーの元の入力が入力された状態でサーバーがフォームを再レンダリングすることで緩和できますが、クライアント側の検証はさらに高速です。)

サーバ側

悪意のあるユーザーから保護できるため、サーバー側で検証したいJavaScriptを簡単にバイパスして危険な入力をサーバーに送信できるからあります。

UIを信頼するのは非常に危険です。彼らはあなたのUIを乱用するだけでなく、あなたのUIをまったく使用していないかもしれません。ユーザーが手動でURLを編集したり、独自のJavascriptを実行したり、別のツールでHTTPリクエストを微調整したりしたらどうなるでしょうか。curlたとえば、スクリプトからまたはスクリプトからカスタムHTTPリクエストを送信するとどうなりますか?

これは理論的なものではありません。たとえば、ユーザーの検索を多くのパートナー航空会社、バス会社などに送信して、POST、ユーザーが各会社の検索フォームに入力し、収集してソートしたかのようにリクエストをしましたすべての結果。これらの企業のフォームJSは実行されなかったため、返されたHTMLにエラーメッセージを表示することが重要でした。もちろん、APIは良かったでしょうが、これは私たちがしなければならなかったことです。

これを許可しないことは、セキュリティの観点から単純であるだけでなく、非標準でもあります。クライアントは、彼らが望むあらゆる方法でHTTPを送信することを許可されるべきであり、あなたは正しく応答するべきです。これには検証が含まれます。

サーバー側の検証も重要です 互換です。ブラウザを使用している場合でも、すべてのユーザーがJavaScriptを有効にするわけではありません。

補遺-2016年12月

データベースの現在の状態に依存するため、サーバー側のアプリケーションコードでは適切に実行できず、クライアント側のコードでは完全に検証できない検証があります。たとえば、「他の誰もそのユーザー名を登録していません」、「コメントしているブログ投稿はまだ存在しています」、「要求された日付と重複する既存の予約はありません」、「アカウントの残高はまだその購入をカバーするのに十分です」 」データベースだけが、関連データに依存するデータを確実に検証できます。開発者は定期的にこれを台無しにしますが、PostgreSQLはいくつかの優れたソリューションを提供します


30
これでも6年後、受け入れ答えなければなりません:P
ジェイコブ・マッケイ

17
はい、確かに10年近く待たなければなりませんでした。
Brad8118 2017年

2
@kidmosey「DRY原則の明らかな違反です」はい、それは私たちのようなプログラマーにとって苦痛を意味します。しかし、登録フォームを想像してみてください。「電子メールアドレスには@が含まれている必要がある」という知識をクライアントコードに複製すると、ユーザーはより迅速なフィードバックを得て、より多くのユーザーがサインアップし、結果として年間10万ドルの追加収入となり、追加のメンテナンスコストを支払うだけでは不十分です。DRYは非常に優れた原則ですが、唯一の考慮事項ではありません。コードの品質は、実際には、費用対効果分析でユーザーと組織にどれだけ役立つかで測定されます。
Nathan Long

1
@ArunRaajはい、そうすればほとんどの問題をその方法で検出できますが、100%信頼できるわけではありません。2人のユーザーが同時にフォームに入力している場合、両方がuser1利用可能なユーザー名であることを両方に通知される場合があります。送信すると、サーバー側を再確認しない限り、どちらも同じユーザー名を取得します。また、サーバーアプリケーションコードのチェックでも同じ問題が発生する可能性があります。最初のリクエストはデータベースをチェックしてOKと通知され、2番目のリクエストはデータベースをチェックしてOKと通知され、最初のリクエストは保存され、2番目のリクエストは保存されます複製として。db一意制約のみが一意性を保証します。
Nathan Long

1
@NathanLong競合状態の影響を受けやすいデータの検証は、この文が妥当であるほど難しくはありません。適切に行うのは面倒ですが、同期されたリソースを使用してリクエストする予約メカニズムを作成します。したがって、ユーザーが「usernameA」と入力した場合、サーバーで一意性チェックが行われ、複数の同時呼び出しで一意かどうかをチェックできません。一意の場合は、クライアントに割り当てられた一時トークンで予約します。これは、同じセッションIDで別のユーザー名がテストされた場合にも解放されます。トークンは妥当な時間の後に期限切れになるはずです。例:チケットマスターの座席予約。
Elaskanator

79

はい、常にクライアント側の検証を完全にバイパスできます。より良いユーザーエクスペリエンスを提供するためにクライアント側と、取得した入力が実際に検証され、クライアントによって検証されただけではないことを確認するためのサーバー側の両方を実行する必要があります。


43

それは非常に重要なので、私はそれを繰り返すつもりです:

常にサーバーで検証する

ユーザー応答性のためにJavaScriptを追加します。


31

クライアント側の検証よりもサーバー側の検証を行う利点は、クライアント側の検証をバイパス/操作できることです。

  • エンドユーザーはJavaScriptをオフにすることができます
  • データを送信するように設計されたカスタムアプリを使用して、サイトを使用していないユーザーがサーバーに直接送信する可能性があります
  • ページ上でJavascriptエラーが発生すると(多くの原因が原因)、検証のすべてではなく一部が実行される可能性があります

つまり、常にサーバー側を検証し、クライアント側の検証をエンドユーザーエクスペリエンスを強化するための追加の「追加」と見なします。


18

サーバーで常に検証する必要あります。

また、クライアントで検証を行うことはユーザーにとって便利ですが、まったく安全ではありません。


9

まあ、私はまだ答える余地を見つけます。

RobとNathanからの回答に加えて、クライアント側の検証が重要であることを付け加えます。Webフォームに検証を適用するときは、次のガイドラインに従う必要があります。

クライアント側

  1. Webサイトの正規のユーザーからの正規のリクエストをフィルタリングするには、クライアント側の検証を使用する必要があります。
  2. サーバー側の処理中に発生する可能性のあるエラーを減らすために、クライアント側の検証を使用する必要があります。
  3. クライアント側の検証を使用してサーバー側のラウンドトリップを最小限に抑え、ユーザーごとの帯域幅と要求を節約する必要があります。

サーバ側

  1. クライアント側で正常に行われた検証が100%完全であると想定しないでください。ユーザー数が50人未満であっても問題ありません。どのユーザー/従業員が「悪」に変わるかわからず、適切な検証が適切に行われていないことを知って、有害なアクティビティを実行することはありません。
  2. 電子メールアドレス、電話番号の検証、またはいくつかの有効な入力のチェックに関して完全であっても、非常に有害なデータが含まれている可能性があります。どちらが正しいか正しくないかに関係なく、サーバー側でフィルタリングする必要があります。
  3. クライアント側の検証がバイパスされる場合、サーバー側の検証により、サーバー側の処理への潜在的な損傷からユーザーを救うことができます。最近では、SQLインジェクションや、いくつかの邪悪な利益を得るために適用される可能性のある他の種類の手法について、多くの話を聞いています。

どちらの種類の検証も、それぞれのスコープで重要な役割を果たしますが、最も強力なのはサーバー側です。ある時点で1万人のユーザーを受け取った場合、Webサーバーに送信される要求の数をフィルターにかけることになります。無効なメールアドレスなどの単一の間違いが見つかった場合は、フォームを再度ポストバックし、ユーザーに修正を依頼します。これにより、サーバーのリソースと帯域幅が確実に消費されます。したがって、JavaScript検証をより適切に適用する必要があります。JavaScriptが無効になっている場合、サーバー側の検証が役に立ちます。99.99%のWebサイトがJavaScriptを使用しており、すべての最新のブラウザーでJavaScriptがデフォルトで既に有効になっているため、数人のユーザーだけが誤って無効にした可能性があります。


私は、コードインジェクションから完全に保護することを怠っている人を見てきました。クライアント側でのみそれを行うことを気にしないでください。そして、これへのリンクがないと、コードインジェクションへの参照は完了しません:xkcd.com/327 :)
Stewart

8

サーバー側の検証を実行し、各フィールドの検証結果を含むJSONオブジェクトを返送して、クライアントのJavaScriptを最小限に抑え(結果を表示するだけ)、クライアントとサーバーの両方で繰り返す必要がなく、ユーザーフレンドリーなエクスペリエンスを維持できます。


3
使いやすい?多分。ほぼ瞬間的でバターのように滑らかですか?おそらく違います。
quadrupleslap

4

クライアント側では、HTML5の入力タイプパターン属性を介した基本的な検証を使用する必要があります。これらは、ユーザーエクスペリエンスを向上させるためのプログレッシブな機能強化にのみ使用されるためです(それらが<IE9およびSafariでサポートされていない場合でも、それらには依存しません)。ただし、主な検証はサーバー側で行う必要があります。


「しかし、主な検証はサーバー側で行われるべきです。」すべきではありません。
スチュワート


2

JavaScriptは実行時に変更できます。

サーバー上で検証構造を作成し、これをクライアントと共有するパターンを提案します。

たとえば、両端に個別の検証ロジックが必要です。

"required"inputsクライアント側の属性

field.length > 0 サーバ側。

ただし、同じ検証仕様を使用すると、両端で検証をミラーリングすることの冗長性(および誤り)がいくつかなくなります。


2

クライアント側のデータ検証は、ユーザーエクスペリエンスを向上させるのに役立ちます。たとえば、私が自分の電子メールアドレスを誤って入力したユーザーは、リモートサーバーによって要求が処理されるまで待たずに、入力ミスについて知る必要があります。

それでも、攻撃者はクライアント側の検証をバイパスできるため(ブラウザをまったく使用しない場合もある)、サーバー側の検証が必要であり、悪意のあるユーザーからバックエンドを保護するための真のゲートでなければなりません。


1

私は、重大で系統的なランダムなエラーを区別する興味深いリンクに出くわしました

Client-Side validationグロスエラーやランダムエラーの防止に最適です。通常、テクスチャと入力の最大長。サーバー側の検証ルールを模倣しないでください。独自の大まかな経験則の検証ルールを提供します(例:クライアント側では200文字n、サーバー側では強力なビジネスルールによって指示されます)。

Server-side validation系統的エラーの防止に最適です。ビジネスルールを適用します。

私が関わっているプロジェクトでは、検証はajaxリクエストを介してサーバー上で行われます。クライアントでは、それに応じてエラーメッセージを表示します。

さらに読む:全体的、系統的、ランダムなエラー:

https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO


-2

簡易検証を行う場合は、クライアントで行うのが最適です。サーバーのパフォーマンス向上に役立つネットワークトラフィックを節約します。データベースまたはパスワードなどの何かからデータを取得することを含む検証が複雑な場合、データを安全にチェックできるサーバーで実行するのが最善です。


2
あなたが独占しているものは最高のアイデアではありません。ユーザーは常にクライアント側の検証をバイパスし、データベースに必要なものを送信できます。
kremuwa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.