フォームに入力された値に行う、入力チェックは(バリデーションチェックとも言うらしいです)大きく分けて、JavaScript で行うクライアント側チェックと、PHP などで行うサーバ側チェックの2つがあります。当然両方で入力チェックを行うことが望ましいのですが、同じようなコードを、クライアント側とサーバ側で書かなければなりません。そこで今回は、入力チェックコードを PHP と JavaScript で共通化する方法を調べてみました。
入力チェックはセキュリティ対策あらず
私も誤解していたのですが、クライアント側とサーバ側両方で、入力チェックを行っていたとしても、クロスサイトスクリプティングなどへのセキュリティ対策にはなりません。
また、クロスサイト・スクリプティングの脆弱性への対策における「入力チェック」は、そもそも漏れが 生じやすく、根本的な対策にはなりません。1 章 5 節「クロスサイト・スクリプティング」の根本的対策の 内容を参考に、対策を検討してください。
IPA 安全なウェブサイトの作り方(改訂第7版)P91 より引用
入力チェックの目的は、ユーザの利便性向上や、データの整合性を確保することです。(完全性の観点から見ればセキュリティ対策とも言えますね)
2重チェックの問題点
下の図では、クライアント側で「check.js」にて入力チェックを行い、POST先のサーバ側でも「check.php」で入力チェックを行っています。
フォームの数が少なく、入力チェックが簡単なものであれば、入力チェックのコードを、JavaScript と PHP それぞれに書いても、さほど大変ではありませんが、業務系のWEBシステムなど、入力フォームが多く、入力チェックが複雑なものになってくると、実装やテストの手間が増えることはもちろんですが、クライアント側とサーバ側で、入力チェックが一致しないなどの不具合にも繋がります。
共通化する方法
WEB系のプログラマーの方なら、すぐにピンとくると思いますが、ajax を使います。
入力チェックのコードは「validation.php」にまとめ「check.php」と「api.php」が利用します。「check.js」は入力された値を、ajax通信で「api.php」に投げるだけで、入力チェックの処理は「validation.php」が行い、結果を「check.js」に返します。
登場人物が多くなるので複雑に見えますが「check.js」と「check.php」のコードが、かなりスッキリします。
サンプルコード
もろもろの処理が雑ですが、サンプルコードです。ご参考まで
$(function() { $('input').focusout(function() { $.ajax({ url : 'api.php', type : 'post', dataType : 'json', data : { name : $('input[name=name]').val(), postno : $('input[name=postno]').val(), address : $('input[name=address]').val() } }) .done(function(response) { $('#name').text(response['name']); $('#postno').text(response['postno']); $('#address').text(response['address']); }) .fail(function() { alert('通信エラー'); }); }); });
<form action='check.php' method='post'> <p>お名前: <input type='text' name='name'><span id='name'></span></p> <p>郵便番号:<input type='text' name='postno'><span id='postno'></span></p> <p>住所: <input type='text' name='address'><span id='address'></span></p> <p style='padding-left: 100px;'><input type='submit' value='送信'></p> </form>
<?php class validation { public static function check($params) { $respons = array( 'name' => '', 'postno' => '', 'address' => '', ); if (!$params['name']) { $respons['name'] = 'お名前を入力してください'; } if (!preg_match('/^[0-9]{3}-[0-9]{4}$/', $params['postno'])) { $respons['postno'] = '郵便番号は「000-0000」の形式で入力してください'; } if (mb_strlen($params['address']) > 100) { $respons['address'] = '住所は100文字以内で入力してください'; } return $respons; } }
<?php require_once('validation.php'); $response = validation::check($_POST); header('X-Content-Type-Options: nosniff'); echo json_encode($response);
<?php require_once('validation.php'); $response = validation::check($_POST); foreach ($response as $mesg) { if ($mesg) { echo "<p>" . $mesg . "</p>"; } }
終わりに
今さらながら、最近 ajax をよく使います。画面を遷移せずに、サーバ側で色々な処理をできるのは本当に便利ですね。(^^)
コメント