パスワードはハッシュ化する!!紙屋02

こんにちは!
’23年度入社の紙屋です!
日に日に暑さが増すなか、台風もやってきて大変ですね。
私は出身が鹿児島県なので台風には慣れっこです。
学生のうちは台風が来ると「学校が休みになるんじゃないか」とそわそわしていましたが、社会人になると「台風きたら出勤どうしよう…」と不安でそわそわしてしまいます(笑)

現在は、課題として会員登録フォームをPHPでの実装、その後フレームワークを使った実装がひと段落終えたところです。調べながら、分からないところが教えていただきながらの実装だったので、ちょっとずつまとめをしていこうと思います。

まずはとりあえず機能の実装を!と考え、新規登録フォーム、検索機能、編集・削除機能を実装しました。その中でセキュリティ対策への考えはまだまだ足りず、データベースへ登録する際に、エスケープ処理を行わなければならないことは覚えていましたが、パスワードに対しては何も処理をしていませんでした。
レビューいただいた際に、「え・・ハッシュ化って?」「まだ処理がいるの?」と混乱しました…。なので、今回はハッシュ化について調べてみました。

今回、PHPプログラミングで実装した内容は、

です。
最初は直観的に

をそのままDBに登録していました。

レビューいただいた際に、このままでは、DBを攻撃された場合、個人情報が盗まれてしまう危険性があると教えていただきました。

確かに!ログイン情報を盗まれてしまったらなりすましなんて簡単にできますね。

password_hash関数をマニュアルで調べてみると、


◦$passwordには登録するパスワードの値が入って、
◦$algoにはハッシュ化に使用するパスワードアルゴリズム定数が入って、
◦$optionsには各アルゴリズムがサポートするオプションが入る
とのこと!

アルゴリズム定数のPASSWORD_BCRYPTを使うと
◦”$2y$” crypt フォーマットを使ったハッシュになる
◦長さは常に 60 文字
◦オプションのcostは省略時はデフォルトの10が入り、ハードウェアの性能が許容できるなら高くも設定可

とのことでした。
上記のpassword_hash()関数で登録しなおすことで、

ちゃんとハッシュ化されていました。
これで一安心です!

知らないことが多くて調べて、コーディングして、エラーと闘う日々です。
今後も、いろいろと忘れないようにまとめていきたいと思います。
では、また次回!!

[Laravel] 値検査(バリデーション)について

福岡拠点の野田です。
秋雨や台風が気になりますが、過ごしやすい日々が増えてきたと思います。
今日は、Laravel の値検査の仕組みについて取り上げようと思います。

Laravel には値検査を行う設計の方向性として大きく3つの選択肢があります。
・FormRequest を継承してリクエストフォームオブジェクトを作る
・ValidatesRequestsトレイトを使う
・Validator ファサードを使う

FormRequestを作る場合

Controller に対して Illuminate\Foundation\Http\FormRequest 型のメソッドインジェクションを指定しておくとそのメソッドに対応するURLが呼び出された際に値検査がかかるという仕組みになります。バリデーションの結果が false の場合、リクエスト値をセッションに保存して、リクエストを投げた前のページに戻ります。

とても便利な仕組みですが、都度、FormRequestを実装することになります。毎回似たようなコードを書くのは煩わしいですよね。そこで以下のような基底クラスを作成して継承して使いまわすことにします。この基底クラスは、自分のクラス名からバリデーションの設定を読み込んで動作する仕組みで動いています。

以下は、config/validation.php の記述例です。FormRequest実装クラス名をキーに設定を記述するとそれを読み込んでくれる仕掛けになっています。クラスの型を利用しつつ、リクエスト値の検査は設定ファイルを利用してカスタマイズしやすくします。

さらにテンプレート側に目を向けてみましょう。入力フォームのテンプレートは、エラー表示と「戻る」ボタンで遷移の両方を共通で実現している場合がほとんどだと思います。Laravel で用意されている old ヘルパーメソッドで取得できるのは、エラー時のセッションしかありませんので、以下のような記述をすることでエラー時のセッション値があれば、セッション値、なければリクエスト値をとる実装が可能です(old メソッドのデフォルト値にリクエスト値を設定する実装になります)。

エラーを表示する場合は以下で対応できます。

$errors->has(’email’)や$errors->count()などもよく使うメソッドだと思います。エラーは MessageBag というクラスで定義されていますので、以下を参考にしていただければ幸いです。

https://laravel.com/api/5.6/Illuminate/Support/MessageBag.html

ValidatesRequestsトレイトを使う場合

FormRequest の処理のうち Controller 側の処理を切り出したものが ValidatesRequest になります。
Controller で use ValidatesRequest をすることで Controller 中で $this->validate() メソッドなどが使えるようになります。

以下 Laravel マニュアルページより

値検査に失敗すると Illuminate\Contracts\Validation\ValidationException が発生し、FormRequest 同様、前のページに戻ります。validateをかけるタイミングを調整できるため、リクエスト値の前処理が必要な場面や FormRequest の作成をしたくない場合に使われると思いますが、Validator ファサードの選択肢もあるため、相対的に利用する場面は少ないと思われます。

Validatorファサードを使う場合

Validator ファサードを使えば値検査部分だけを部品化して値検査をすることが可能です。バッチ系で値検査を行うときは直に呼び出して使うことが多いと思います。例えばCSVインポートバッチの入力値チェックなどはこの Validatorファサードの出番です。

上記は、config/validation.php で設定を外だししている例です。個別実装することももちろん可能ですが、ある程度共通化できるところは共通化しておくと良いでしょう。

まとめ

なんだかんだいいましたが、場面場面に応じて最適な値検査の方法を選択して実装していくとよいでしょう。その中で特に伝えたかったことが「設定ファイル化」という部分になります。値検査(バリデーション)というプログラムの課題の中でconfig/validation.php にまとめておく、HTML部品という課題の中で config/form.php にまとめておく、アプリケーション設定として、config/const.php にまとめておく、などなどです。後で入力チェックをまとめるときに個別の実装をみなくてよいのは、大きな助けになると思います。まだの方は、実装時の良い習慣としてプログラムの課題の設定ファイル化を是非やってみてください。

補足

以下補足になります。入力、確認、完了のような遷移がある場合のルーティングのTIPSです。通常、入力画面は、GETリクエスト、それ以外はPOSTリクエストとしていると思います。つい忘れがちですが、保存ページについては、GETも受け付けて入力画面に逃がすとよいと思います。戻すときの遷移でリロードして、MethodNotAllowedのエラーが見えてしまうとちょっとカッコ悪いですよね。

君はマーティン・ファウラーを知っているかい?

いかがお過ごしでしょうか。福岡拠点の野田です。
春は新しい生活がはじまる季節です。初心に返って今日はマーティン・ファウラーの話を少し。

ソフトウェアの設計の世界でマーティン・ファウラーを知らない人はいないと思います。ThoughtWorksに所属し、アジャイルソフトウェア開発宣言の起草を支援するなど、ソフトウェア開発業界に数多くの影響を与えている人です。

https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%83%BB%E3%83%95%E3%82%A1%E3%82%A6%E3%83%A9%E3%83%BC

私がマーティン・ファウラーを初めて知ったのは、2005,6年ごろ依存性注入(DI: Dependency Injection)が話題になったころ。今では多くのフレームワークに採用され、当たり前となった概念も当時は目からうろこでした。

http://kakutani.com/trans/fowler/injection.html
https://ja.wikipedia.org/wiki/%E4%BE%9D%E5%AD%98%E6%80%A7%E3%81%AE%E6%B3%A8%E5%85%A5

DDDで基本となるValueObjectをPoEAAで紹介していたり、マイクロサービスについて語っていたり、設計の世界では伝道師的な存在だと思っています。

http://kimitok.hateblo.jp/entry/2014/11/09/211820
https://martinfowler.com/bliki/ValueObject.html

まだ知らなかった方はこれを機会に是非記事を読んでみてください。発表されてから時間の経つものが少なくないですが、いまでも通用するものが数多くあります。

気になる本家サイトは、こちら。

https://martinfowler.com/

英語サイトの日本語訳をやっている方々もいらっしゃいますので、ご参考まで。

http://bliki-ja.github.io/