⛓️

CakePHPのAuthComponentからAuthenticationへの移行

に公開

概要

CakePHPの認証は2系ではAuthComponentがデフォルトの方法でしたが、4系で非推奨になり、5系で削除されています。
AuthComponentの代わりとしてAuthenticationとAuthorizationの2つのプラグインを利用するようになりました。
CakePHPの2系から動いているシステムをバージョンアップするにあたって、5系ではAuthComponentが削除されているため、移行の方法を検討しました。

結論

公式のドキュメントにmigration guideがあるので参照しながら進めましょう。
ドキュメントに従って実行すれば、割と簡単にできます。
https://book.cakephp.org/authentication/1/en/migration-from-the-authcomponent.html

認証のバージョンアップでよく話題となるパスワードのハッシュ方法の変更についても既存のライブラリで提供されているため、スムーズに移行できました。

詳細

認証について

CakePHPの2系や3系では、認証はAuthComponentを利用していましたが、CakePHP4系以降ではAuthenticationとAuthorizationの2つのプラグインが推奨されるようになりました。
どこかで読んだ気がするのですが、認証と認可が混ざっていて複雑になっていたために2つに分割しているようです。

https://book.cakephp.org/4/ja/appendices/4-0-migration-guide.html

認証機能がスタンドアロンのプラグイン Authentication および Authorization に分割されました。
AuthComponent および関連するクラスは廃止され、 5.0.0 で削除されます。代わりに、 上記の認証および認可ライブラリを使用する必要があります。

CakePHPを最新のバージョンである5系にするにあたって、AuthComponentは削除されているため、アップデートする必要がありました。

移行方法

CakePHPのマイグレーションガイドにはさらっとしか乗ってないのですが、AuthenticationのPluginのドキュメントを見ると移行方法が記載されています。
https://book.cakephp.org/authentication/1/en/migration-from-the-authcomponent.html

基本的には記載されている通りに移行ができればOKです。

AuthComponentでの記述

AppController.php(CakePHP 2.x)
$this->loadComponent('Auth', [
    'authentication' => [
        'Form' => [
            'fields' => [
                'username' => 'email',
                'password' => 'password',
            ]
        ]
    ]
]);

Authenticationでの記述

Application.php
// Instantiate the service
$service = new AuthenticationService();

// Load identifiers
$service->loadIdentifier('Authentication.Password', [
    'fields' => [
        'username' => 'email',
        'password' => 'password',
    ]
]);

// Load the authenticators
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form');

移行前をCakePHP2系としているので、処理を記載するクラスも変わっています。
loadIdentifierで指定できるオプションは以下にまとまっています。
https://book.cakephp.org/authentication/1/en/identifiers.html

Hash

対象となるシステムではsha1を利用してパスワードをハッシュ値にしていました。
AuthenticationのPluginではPHPのbcryptを利用しているため、そのままでは既存のユーザーに対して認証が通りません。
そのため、bcryptのハッシュ値で突合した後にsha1で突合するような設定としました。

Application.php
$service->loadIdentifier('Authentication.Password', [
    'fields' => [
        'username' => 'email',
        'password' => 'passwd',
    ],
    // この部分
    'passwordHasher' => [
        'className' => 'Authentication.Fallback',
        'hashers' => [
            'Authentication.Default',
            [
                'className' => 'Authentication.Legacy',
                'hashType' => 'sha1'
            ],
        ]
    ]
]);

上記の方法では、まずはデフォルトの方法で認証を行い、次にLegacyな方法(指定のハッシュタイプ)で認証を行います。
処理を行っているのはこの辺
https://github.com/cakephp/authentication/blob/3.x/src/PasswordHasher/LegacyPasswordHasher.php

おわりに

CakePHP2系から利用されているAuthComponentをAuthenticationに移行を行いました。
別々のプラグインに分かれているので、大幅な修正が必要かと思いきや、意外と簡単に実装自体は完了しました。
※ もちろん、記事にしてない部分で設定などが上手くいかずに調査しまくっていました

処理を全般的に理解したかったので、Authenticationの処理はある程度理解できたので、どこかのタイミングでまとめて記事に出来ればと思います。

DELTAテックブログ

Discussion