パスワードをハッシュ化する – CakePHP3でサイト開発 Part.3

このシリーズは、CakePHP3 系で web サイトを開発する一連の流れの解説になります。前回は AuthComponent を利用して CakePHP3 のアプリケーションに認証ロジックを追加しました。

連載第3回である本記事は、CakePHP3 の標準機能にある DefaultPasswordHasher を用いてパスワードをハッシュ化する方法を記述します。

DefaultPasswordHasher の利用

実装方法は単純で、以下のマニュアルのようにパスワードをハッシュ化したいエンティティにアクションを記述します。これを実装すると、データベースに値が保存される直前でハッシュ化されるため、パスワードのバリデーションに影響されない設計となっています。

CakePHP3 公式マニュアル パスワードのハッシュ化

namespace App\Model\Entity;

use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;

class Member extends Entity
{
    protected function _setPassword($password)
    {
          return (new DefaultPasswordHasher)->hash($password);
    }
}

AuthComponent は標準で DefaultPasswordHasher を利用するため、特別な理由がない限りパスワードのハッシュ化はこれを利用した方が無難と思われます。なお、この場合のハッシュ化アルゴリズムは bcrypt になります。この方法を用いてパスワードのハッシュ化を行う場合、CakePHP3 では php の password_hash 関数を利用するため、ハッシュ化された値の長さは 60 文字です。ただし、今後変更される可能性もあるので、php の公式マニュアルに従ってカラムの長さは 255 に指定した方が無難と思われます。

php 公式マニュアル パスワードのハッシュ化

上記処理内、_set から始まるメソッドはミューテーターと呼ばれるもので、プロパティがどのように保存されるべきか指定するものです。_set + プロパティ名(カラム名)で定義する必要があり、キャメルケースで記述しなければいけませんので、_setPassword としました。なお、指定するフォーマットを返却する必要があるので、return の後ろに続けてフォーマットを記述しました。

CakePHP3 公式マニュアル アクセサーとミューテーター

ハッシュ化の確認

早速ハッシュ化した値をデータベースに保存して確認してみます。エラーチェックやアソシエーションなど色々やりたいことがありますが、今はハッシュ化についてフォーカスするために一旦無視します。コントローラ内、パスワードの保存を行いたい箇所で以下のように記述します。

$member = $this->Members->newEntity();
if ($this->request->is(['post', 'put'])) {
    $member = $this->Members->patchEntity($member, $this->request->data);
    $this->Members->save($member);
}

これでコントローラ内でパスワードを保存する準備ができました。Templete ファイルにパスワードを POST できるように記述して、パスワードを送信してみてください。データベースの中に無事ハッシュ化された値が格納されているかと思います。

平のパスワードとハッシュ化されたパスワードの一致確認

ついでにハッシュ化される前のパスワードとハッシュ化された後のパスワードが一致しているか確認する方法を記述します。平のパスワードとハッシュ化されたパスワードの比較ですが、これも CakePHP3 が標準で準備しているので、それを利用します。マニュアル内で解説されている箇所を見つけられなかったので、ソースコード内、実装されている箇所を以下に挙げます。

//ファイルの置き場所
app/vendor/cakephp/cakephp/src/Auth/DefaultPasswordHasher.php

class DefaultPasswordHasher extends AbstractPasswordHasher
{
    public function check($password, $hashedPassword)
    {
        return password_verify($password, $hashedPassword);
    }
}

コントローラ内に以下を記述して、直接値を入力してみてどのような結果が得られるか確認してください。

//現在のパスワードの確認
$hasher = new DefaultPasswordHasher();
if($hasher->check('平のパスワード', 'ハッシュ化されたパスワード')){
    debug('Password is Correct');
}else{
    debug('Password is Wrong');
}
終わりに
何か不明点があれば、サイト TOP のお問い合わせよりご質問ください。また、より CakePHP3 について詳しく知りたい方は、現在公式マニュアルの翻訳を行っていますので一緒にやりませんか?

CakePHP3 の公式マニュアルを翻訳する方法

Enjoy!!