2015.7.13
0からはじめるPHP#33【Laravel5で作るデータベース#7-設計を反省する&バリデーション-】
前回「設計を知る」なんて知ったかぶったタイトルをつけておきながら
その直後に反省するなんて何がしたいねんって感じですけど、まぁ最初はそんなもんです。たぶん。
とりあえず、改めて設計したのがこれです。
だいぶ前に作ったんですが、ご飯食べてたらなんか汚れました笑
設計といってもクラス図とかじゃなく、ただ図にして書いただけです。どの処理が統合できそうか、どこを分割しなければいけないか、というのを改めて図にして考えています。
また、変数もなるべくコンパクトに、かつ分かりやすくまとめる努力をしてみました。まぁ、そんなに深く考えずに作ってますし、既に基盤を作った後なのでそれに多少なりとも合わせなくてはいけなかったんでちょっと合理化できてない部分は少し・・・・・・
まぁ多々あるんですけどこういう経験の積み重ねが後々活きてくると思うのです。
こうやって反省していくわけですね。
ただ、プログラミングの基本ですけど
再利用できるものは再利用する(できるようにする)というのを意識すると、機能の拡張も容易にできますし、あとエラー修正もかなーーーりラクになります。この辺は基礎的な知識があれば、関数化するなりパーツに分解するなり色々やり方はあるかなと思います。
設計の話をしようと思ったんですが、別にわざわざ内部構造をオープンにする必要もないので、反省はこの辺にしておいて、次は
セキュリティの話をしたいと思います。
単なるプログラミングなら気にする必要はない話なのですが、僕がやりたいのはWebアプリケーションです。セキュリティのことも考えなければなりません。
セキュリティに対する知識があると、お金が関わるアプリケーションの運用もしやすくなると思います。未来があるんですね。
それに、セキュリティ意識のないプログラマはゴミだと思いますし。技術が云々ってのは後からついてくると思います。大事なのは意識することだと思います。
データベースといえば真っ先に考えなくてはいけないセキュリティ対策は
SQLインジェクションの話ですね。
この辺の話は
実は#22でやってるんで、原理を知らない方はこちらで。
SQLインジェクションはクエリービルダーを用いてるのでLaravelの方で勝手に対策してくれてるので特に考えなくてもいいんですが、
SQLセカンドインジェクションになると、今度は表示の問題なので、こちらで対策しなければなりませんね。フレームワークだから安全、というわけではないです。ただ、その対策を少しラクにしてくれる、というだけです。
さて、セキュリティ対策と一口でいっても具体的にどこからどこまで対策したらいいのかは分からないものです。
そこで
Webアプリケーションの脆弱性を総括する(@IT)というページがありました。ここに書いてあるセキュリティ対策をやっとけばいいかなって感じですね。他にもいろいろとあると思うのですが、それは知識が深くなってからでいいかなと。
この中で
入力チェックに相当するのが、今回お話する
バリデーションで対策できるものになります。
入力チェックはブラウザ側でjavascriptかなんかでエラーを出して、送信を止めることもできるのですが、javascriptはご存知の通り、改ざんが容易に可能です。悪意があればくぐり抜けることはできるそうです。やり方は知りませんけど、ブラウザに付属してるjavascriptコンソールからjavascriptの命令を実行できるので、たぶんそれを使うんじゃないかなーと思います。
つまり、ユーザーは悪意を持ってデータを送信することができる、ということです。だから、POSTメソッドだからといって安心してはいけません。入力された値が正しいかどうかをチェックしなければなりません。
以下にちょっとした例を作ってみます。
マニュアルはこちら。コントローラーバリデーションです。
public function __construct(Request $request)
{
self::Sample($request);
}
private function Sample($request){
$this->validate($request, [
'title' => 'required|unique|max:255',//必須+他テーブルとの重複禁止+255以下 複数条件指定は"|"(パイプ)で区切ります
'body' => 'required',//必須
'mail' => 'email',//メールアドレスとして正しい
]);//受け取った$requestをバリデーション 違反があればリダイレクトされます。
$v=[
'title' => 'required|unique|max:255',
'body' => 'required',
'mail' => 'email',
]
$this->validate($request,$v);//もちろん配列に入れても良い
}
コードをテストしたわけじゃないので動かないかも知れませんが、具体的な使い方はこんな感じです。
もちろん、コンストラクタで実行してもいいですし、たぶん大体の場合はそれでいいんじゃないかと思います。
僕の場合は設計がウンコでそれが不可能でした。
不正な値が入力されるとリダイレクトされるってのがまた扱いやすくていいですね。if分岐とか要らないですし。もちろん、エラーメッセージを表示させることも可能なようですが、めんどくさいのでこれに関してはまた別の機会に学習したいなと思います。
何がともあれ、これで入力値のチェックが行えます。直感的で分かりやすいのでこれで全ての入力値をチェックしましょう。特に、受け取ったデータをどこかで表示する可能性があるものはバリデーションをかけないと脆弱性が発生し、最悪の場合データベースを破壊されたり、情報を盗まれたりします。
そうでなくても、さすがフレームワークといいますが、とても扱いやすいと思うので単なるエラーチェックにでもどうぞ。
ただ、不正な文字列を排除するのは、これだけでは足りないようです。セキュリティのことを考えると
制御文字を排除したいという要望があると思うのですが、これはこのままでは叶えられません。
もちろん、制御文字を排除するのがベストというわけではありませんが
(制御文字を使用してはいけないという制約が発生するので)そもそも制御文字が入る必要がないパラメーターに関しては、最初からバリデーションしておくとリスク軽減につながります。
僕は使ってないので
リンクだけ貼っておきますが自分でクラスを作ることで対処できるようです。
コメントフォームなどのテキスト入力があるところでは定義した方が良さそうですね。
デフォルトで入れてくれたらいいのに。
このデータベースに関してはもう特に話すことがなくなってきて、あとは実装だけって感じですね。
まぁ後は認証の話と、細々した話をちょろっとして、このデータベースのシリーズを終わらせたいなーと思ってます。