ColdFusionカフェテリア
SAMURAIZ
| ↑一覧へ戻る |
ColdFusionクリニックへようこそ

こんな症状には注意A 〜ユーザーが入力するデータのチェック〜

作成日: 2015年12月
最終更新日: 2015年12月

■検診してみましょう。

今回も患者Aさんの話ですね。上司のBさんからの指示で、ユーザーから渡されたアーティストのIDの値をもとに、該当する作品データを取得する処理を作る事を任されたそうです。

当初、話を聞いたAさんは、フォームと<cfquery>を組み合わせれば簡単にできるような事をなんで自分が。。。と少し不満に思いつつ、さっとプログラムを組んでBさんに見てもらうことにしました。

Bさんはプログラムを動かすことなく、コードをじっと眺めながら難しい顔をしていました。そしてAさんに「このプログラムをそのまま本番で動かしたらどういう問題が起こると思う?」 と尋ねたそうです。

その時のAさんのプログラムを要約したものが下記になります。

<cfform>
	アーティストIDを入力(数字): <cfinput type="text" name="AID">
	<cfinput type="submit" name="submit" value="作品検索">
</cfform>

<cfif IsDefined("Form.submit")> 
  <cfquery datasource="cfartgallery" name="qArt">
    SELECT * FROM ART
    WHERE ARTISTID = #Form.AID#
  </cfquery>
  <cfoutput query="qArt">
    #qArt.ARTNAME#(#qArt.DESCRIPTION#)<br>
  </cfoutput>
</cfif>

見る限りでは特に構文エラーなどの間違いも無さそうですが、Aさんのプログラムはどんな問題を含んでいたのでしょうか。

■気付きましたか?

ポイントは、Bさんの言った「本番で動かす」という点です。テストと本番運用の違いは何でしょうか?「機器が違う」「データがテスト用と本番用で違う」といった違いはすぐに想像できると思いますが、もう一つ重要な点があります。それは「そのページを利用する人が違う」です。

開発やテスト段階では、操作やデータの入力を当たり前のようにしていた事も、いざユーザーが使ってみると分かりにくい画面や不親切な説明だったりします。思わぬ操作や入力をされてしまいエラーや予想外の結果を招く事も。。。ユーザーがそのページを見てどのように感じるか、そして行動をするかについてを考え、システム側でそれを補いサイトの品質を上げていく事を考えましょう。

前篇では、主にユーザーの操作面による問題ポイントを紹介します。

@
Aさんは、アーティストIDには数字で管理されているという事が分かっていました。そこで、「アーティストIDを入力(数字)」と記載して、数字を入れるように書きました。しかし、よくわからないユーザーは、あれこれ試していくなかで数字以外の文字を入れてしまうかもしれません。また、誤って全角数字で入力したり、(メールなど別の場所からコピー&ペーストした時に)数字の前後に空白も含まれて入力される事も考えられます。

現在のプログラムでは、値に数字以外を入力してデータを送信すると、SQLのエラーが発生してしまいます。

次の情報は、Web サイト開発者のデバッグに役立ちます。
リクエストを処理する際に、エラーが発生しました。

データベースクエリーを実行する際のエラーです。

Column 'ABC' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'ABC' is not a column in the target table.
エラーの発生位置 C:/ColdFusion11/cfusion/wwwroot/local_link/query/form.cfm: line 9
7 : 	<cfquery datasource="cfartgallery" name="qArt">
8 : 	SELECT * FROM ART
9 : 	WHERE ARTISTID = #Form.AID#
10 : 	</cfquery>
11 : 	<cfoutput query="qArt">
SQLSTATE   42X04
DATASOURCE   cfartgallery
VENDORERRORCODE   20000
SQL    SELECT * FROM ART WHERE ARTISTID = abc
スタックトレース
at cfform2ecfm1001981290.runPage(C:/ColdFusion11/cfusion/wwwroot/local_link/query/form.cfm:9) at cfform2ecfm1001981290.runPage(C:/ColdFusion11/cfusion/wwwroot/local_link/query/form.cfm:9)

java.sql.SQLSyntaxErrorException: Column 'ABC' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE  statement then 'ABC' is not a column in the target table.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
	at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
	at coldfusion.server.j2ee.sql.JRunStatement.execute(JRunStatement.java:359)
	at coldfusion.sql.Executive.executeQuery(Executive.java:1479)
	at coldfusion.sql.Executive.executeQuery(Executive.java:1229)
	at coldfusion.sql.Executive.executeQuery(Executive.java:1159)
	at coldfusion.sql.SqlImpl.execute(SqlImpl.java:406)
	at coldfusion.tagext.sql.QueryTag.executeQuery(QueryTag.java:1185)
	...

※上記は Apache Derby データベースのエラーメッセージです。

Aさんは対策として説明に(数字)と書いていましたが、それだけでは、システム面の備えが足りないということです。入力したデータはデータベース処理の前に事前にチェックをするという事を忘れないようにしていきましょう。

ユーザーにとっても分かりやすいのは、入力画面からサーバーへ送信(サブミット)する前にチェックを行うという事です。入力画面から遷移する事無くチェックできるのはユーザーにも直観的で分かりやすいですよね。でも、ブラウザ上での動作となるため、通常は、JavaScriptなどを使ってゴリゴリとチェックするスクリプトを組む必要がありますが(※最近は HTML5で拡張された検証機能やjQueryの入力チェック機能もあって敷居は大分下がりましたが)、ColdFusion にも <cfinput>タグに入力データのチェック機能があります。この機能を利用するとチェック処理に必要な JavaScript をColdFusionが生成してくれます。該当する箇所だけを抜き出して解説すると

	アーティストIDを入力(数字): <cfinput type="text" name="AID"
	validate="integer" required="true" message="アーティストIDは数字で入力して下さい">

最初のコードと比較してvalidate属性やrequired、message属性が追加されています。属性の名前から想像がつくと思いますが、入力を必須にするには required 属性を yes(true) にします。また、入力するデータの種類を限定するのに validate属性を使用します(検証タイプはこちらの「検証のタイプ」を参照)。message属性には、これら入力チェックに失敗した場合に画面に表示するメッセージを記述して下さい。実行して、誤ったデータを入力(未入力)だと、画面のような JavaScript のダイヤログが表示されます。

 

■今後の予防

会員登録や情報検索など、Webで情報を入力する機会は多いかと思いますが、いざ自分がそのページを作るとなった時、自分の経験をもとに、どのような行動を取るか?どのような入力だとつまずきやすいかなど、考えてみると良いと思います。

入力フォームも、一行入力(type="text")、チェックボックス(type="checkbox")、ラジオボタン(type="radio")の他、選択(cfselectタグ)や複数行入力(cftextareタグ)など、用途に応じて選択していくことも大切です。ユーザーに分かりやすい入力画面を作ることと、誤った操作によるデータベースエラーを防ぐ対策などを行って下さい。

■おくすり出しておきますね〜(まめ知識)

今回、データの入力の話をしましたが、まだまだこれだけでは終わりません。次回は、ユーザーがSubmitした後のアクション側のチェックについても考えていきましょう。

お大事に〜
ColdFusionの各種情報の配信


最新情報
■2017/3/27
ColdFusion 2016 対応
インストール セットアップ情報
CFサーバーのインストール
CFビルダーのインストール

■2016/9/20
『ColdFusion 2016 リリース
Enterprise Edition 活用資料』
記事一覧

■2016/3/30
『ColdFusion 実験室』
実験4、実験5

■2015/8/10 〜
『ColdFusion クリニック』
記事一覧(随時更新中)

■2015/4/8
『JasperReportsによる帳票出力』
2. JasperReportsによる帳票出力【後編】

■2015/3/12
アップクロス株式会社
西元 貞昭様
『JasperReportsによる帳票出力』
1. JasperReportsによる帳票出力【前編】


■2015/2/25
『ColdFusionでエクセルを使いこなそう!』
4. 【上級】ColdFusionのエクセル機能を利用したPDF帳票の紹介

ColdFusionトレーニング


ColdFusionユーザーグループ
ColdFusionユーザーグループ
Copyright 2012 Samuraiz Corporation. All Rights Reserved.