CodeIgniter 4でログイン認証を自動化!フィルタ機能の使い方とセキュリティ対策
生徒
「CodeIgniterで、ログインしていないユーザーがマイページに入れないようにしたいのですが、全てのページにログインチェックを書くのは大変そうです…。」
先生
「そうですね。ページが増えるたびに同じコードを書くのは間違いの元です。CodeIgniterには『フィルタ』という便利な自動チェック機能があるんですよ。」
生徒
「フィルタを使うと、勝手にログインを確認してくれるんですか?」
先生
「その通りです!関所の門番のように、中に入る前にしっかりチェックしてくれる仕組みを一緒に学んでいきましょう。」
1. 認証チェックと「フィルタ」の役割
Webサイトを作っていると、「会員だけが見られるページ」を作りたいことがよくあります。これをプログラミングの世界では「認証(にんしょう)」と呼びます。例えば、自分のプロフィール編集画面や、購入履歴などは、本人以外が見られたら困りますよね。
CodeIgniter(コードイグナイター)というPHPの道具箱(フレームワーク)には、この認証を簡単に行うための「フィルタ(Filters)」という機能が備わっています。フィルタとは、例えるなら「お店の入り口に立つガードマン」のような存在です。お客さんがお店(特定のページ)に入ろうとしたとき、その人が会員証(ログイン情報)を持っているかどうかを、お店の中に入る前に一括で確認してくれます。
もしフィルタを使わずにプログラミングをすると、料理を作る人(コントローラー)が、注文を受けるたびに「あ、あなた会員ですか?」といちいち確認しなければなりません。これでは効率が悪いですし、確認し忘れるミスも起きてしまいます。フィルタを使えば、すべての入り口に一斉にガードマンを配置できるので、安全で効率的なシステムが作れるのです。
2. 認証状態を保存する「セッション」の基本
フィルタの話を進める前に、まず「ログインしている状態」をどうやってプログラムが覚えているのかを知る必要があります。インターネットの世界は、実は「さっきのやり取り」をすぐに忘れてしまう性質があります。そこで使われるのが「セッション(Session)」という仕組みです。
セッションは、サーバー側に用意された「一時的なメモ帳」のようなものです。ユーザーが正しいパスワードを入力してログインに成功したとき、このメモ帳に「この人はログイン済みですよ」という印を書き込みます。そして、次に別のページを開いたとき、そのメモ帳を見て「あ、この人はさっきログインした人だ」と判断するわけです。
以下のコードは、ログインに成功したときにセッションへ情報を保存する、ごくシンプルな例です。
// セッションの準備
$session = session();
// ログイン成功時に「isLoggedIn」という名前で「true(はい)」を保存する
$session->set('isLoggedIn', true);
$session->set('userName', 'たろう');
echo 'ログイン情報をメモ帳に保存しました!';
この「isLoggedIn」という印がメモ帳(セッション)にあるかどうかを、フィルタで確認していくことになります。
3. フィルタクラスを作成してみよう
それでは、実際にガードマンの役割をする「フィルタクラス」を作ってみましょう。CodeIgniter 4では、app/Filters というフォルダの中に新しいファイルを作成します。今回は「AuthFilter.php」という名前にしましょう。
フィルタには主に2つのタイミングがあります。ページを表示する前の「before」と、表示した後の「after」です。認証チェックの場合は、表示する前に確認したいので「before」の中に処理を書きます。もしログインしていなければ、ログイン画面に無理やり追い返す(リダイレクトする)という命令を出します。
namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
class AuthFilter implements FilterInterface
{
// ページを表示する前に実行される処理
public function before(RequestInterface $request, $arguments = null)
{
// セッションを確認する
if (!session()->get('isLoggedIn')) {
// もしログインしていなければ、ログインページへ強制移動!
return redirect()->to('/login');
}
}
// ページを表示した後に実行される処理(今回は空っぽでOK)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// 何もしない
}
}
このコードの中にある redirect()->to('/login') は、不審なユーザーを入り口で止めて、ログイン画面まで連行するようなイメージです。これで、ログインしていない人が勝手に中に入るのを防ぐ準備ができました。
4. フィルタをアプリ全体に登録する
フィルタのファイルを作っただけでは、まだガードマンは動いてくれません。「このガードマンを使いなさい」という指示書に登録する必要があります。その指示書が、app/Config/Filters.php というファイルです。
このファイルの中で、まずは作成した「AuthFilter」に短いあだ名(エイリアス)を付けます。例えば「auth」という名前にしましょう。次に、どのページでそのフィルタを動かすかを指定します。サイト全体で動かしたい場合や、特定のURLだけで動かしたい場合など、細かく設定できます。
namespace Config;
use CodeIgniter\Config\BaseConfig;
use App\Filters\AuthFilter; // 自作したフィルタを読み込む
class Filters extends BaseConfig
{
// フィルタに「auth」という短い名前を付ける
public array $aliases = [
'auth' => AuthFilter::class,
];
// 常に動かしたいフィルタを設定(グローバル設定)
public array $globals = [
'before' => [
// ここに 'auth' を書くと全ページでチェックが走る
],
'after' => [],
];
}
「全ページ」に適用してしまうと、ログイン画面自体にもログインチェックがかかってしまい、永久にログインできないループに陥るので注意が必要です。そのため、通常は特定のルート(住所)にだけ適用するのが一般的です。
5. 特定のページにだけフィルタを適用する方法
全てのページではなく、特定の管理画面やマイページだけに認証チェックをかけたい場合は、ルーティングの設定ファイル(app/Config/Routes.php)で指定するのが便利です。
例えば、「/admin/」から始まるURLはすべてログインが必要にしたい、という設定が可能です。こうすることで、トップページやお問い合わせフォームは誰でも見られるけれど、管理画面だけはしっかり守る、といった柔軟な作り方ができるようになります。
// ルーティング設定の例
$routes->get('admin/dashboard', 'AdminController::index', ['filter' => 'auth']);
$routes->get('admin/profile', 'AdminController::profile', ['filter' => 'auth']);
// グループ化して一気に適用することもできます
$routes->group('user', ['filter' => 'auth'], function($routes) {
$routes->get('mypage', 'UserController::index');
$routes->get('settings', 'UserController::settings');
});
このように設定すると、/user/mypage や /user/settings にアクセスしたとき、自動的にさきほどのガードマン(AuthFilter)が呼び出され、ログインしているかどうかを瞬時に判断してくれるようになります。自分で何度も同じプログラムを書かなくて済むので、非常にスマートですね。
6. セキュリティを高めるための工夫
認証チェックができたら、あわせて覚えておきたいのが「CSRF対策」です。CSRF(シーサーフ)とは「クロスサイト・リクエスト・フォージェリ」の略で、悪い人が作った罠サイトを踏んだ拍子に、勝手にログイン中のSNSへ投稿されたり、パスワードを変えられたりする攻撃のことです。
CodeIgniterでは、この恐ろしい攻撃を防ぐための仕組みも「フィルタ」として最初から用意されています。設定ファイルの $globals の中にある 'csrf' を有効にするだけで、あなたのサイトのセキュリティはぐんと高まります。認証フィルタとCSRF対策フィルタを組み合わせることで、初心者でもプロレベルの安全なWebアプリケーションを作ることができるのです。
セキュリティ対策は「難しいから後回し」にしがちですが、CodeIgniterのようなフレームワークを使えば、設定を少し変えるだけで強力な守り(堅牢性)を手に入れることができます。プログラミングの基本である「再利用性」と「安全性」を、このフィルタ機能を通してぜひ体感してみてください。