CodeIgniterの認証チェックをフィルタで実装する方法!初心者でもわかる完全ガイド
生徒
「CodeIgniterで、ログインしていないユーザーを特定のページから排除する方法ってありますか?」
先生
「はい、CodeIgniterには、フィルタという便利な機能があって、それを使えば認証チェックを簡単に実装できますよ。」
生徒
「フィルタって何ですか?どうやって使うんですか?」
先生
「フィルタは、コントローラーが実行される前や後に自動的に処理を挟み込む仕組みです。これから詳しく解説していきますね!」
1. CodeIgniterのフィルタとは?
CodeIgniterのフィルタとは、ウェブアプリケーションにおいて、コントローラー(ページの処理を担当する部分)が実行される前後に、自動的に特定の処理を実行できる機能のことです。例えるなら、お店に入る前に必ず通る「入口のセキュリティチェック」のようなものです。
フィルタを使うことで、ログインチェック、セキュリティ対策、アクセス制限などを、各ページごとに書く必要がなく、一箇所にまとめて管理できます。これにより、コードの重複を防ぎ、メンテナンスしやすいプログラムを作ることができます。
認証チェックをフィルタで実装すれば、ログインしていないユーザーが管理画面などの重要なページにアクセスしようとした際に、自動的にログインページへリダイレクト(移動)させることができます。
2. フィルタファイルを作成する方法
CodeIgniterでフィルタを使うには、まずフィルタファイルを作成する必要があります。フィルタファイルは、app/Filtersフォルダの中に保存します。
今回は、ログイン認証をチェックするAuthFilter.phpというファイルを作成してみましょう。このファイルの中に、「ログインしているかどうか」を確認する処理を書いていきます。
フィルタファイルには、CodeIgniter\Filters\FilterInterfaceというインターフェース(約束事のようなもの)を実装する必要があります。インターフェースとは、「このクラスには必ずこのメソッドを用意してください」という決まりのことです。
<?php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
class AuthFilter implements FilterInterface
{
public function before(RequestInterface $request, $arguments = null)
{
// ログインチェックの処理をここに書く
if (!session()->get('isLoggedIn')) {
// ログインしていない場合はログインページへリダイレクト
return redirect()->to('/login');
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// コントローラー実行後の処理(今回は使用しない)
}
}
このコードでは、beforeメソッドの中で、セッション(ユーザーの状態を保持する仕組み)にisLoggedInという値が保存されているかをチェックしています。保存されていなければ、ログインページへ自動的に移動させます。
3. フィルタを登録する設定方法
作成したフィルタを実際に使えるようにするには、app/Config/Filters.phpファイルに登録する必要があります。このファイルは、CodeIgniterにどのフィルタをどこで使うかを教えるための設定ファイルです。
Filters.phpを開いて、$aliasesという配列に、先ほど作ったAuthFilterを登録します。エイリアス(別名)を付けることで、短い名前で呼び出せるようになります。
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Filters extends BaseConfig
{
public array $aliases = [
'csrf' => \CodeIgniter\Filters\CSRF::class,
'toolbar' => \CodeIgniter\Filters\DebugToolbar::class,
'honeypot' => \CodeIgniter\Filters\Honeypot::class,
'auth' => \App\Filters\AuthFilter::class, // 認証フィルタを追加
];
public array $globals = [
'before' => [
// 'honeypot',
// 'csrf',
],
'after' => [
'toolbar',
],
];
public array $methods = [];
public array $filters = [];
}
ここでは'auth'という名前でAuthFilterを登録しました。これで、他の場所から'auth'という短い名前でこのフィルタを呼び出せるようになります。
4. ルート設定でフィルタを適用する
フィルタを特定のページ(ルート)に適用するには、app/Config/Routes.phpファイルで設定します。ルートとは、URLとコントローラーを結びつける道筋のことです。
例えば、/dashboardという管理画面のページに認証フィルタを適用したい場合は、次のように書きます。
<?php
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->get('/', 'Home::index');
$routes->get('/login', 'Auth::login');
// 認証フィルタを適用したルート
$routes->get('/dashboard', 'Dashboard::index', ['filter' => 'auth']);
$routes->get('/profile', 'User::profile', ['filter' => 'auth']);
$routes->post('/update', 'User::update', ['filter' => 'auth']);
この設定により、/dashboard、/profile、/updateのページにアクセスする際には、必ずauthフィルタが実行されます。ログインしていないユーザーは自動的にログインページへリダイレクトされます。
複数のページに同じフィルタを適用したい場合も、このように各ルートに['filter' => 'auth']を追加するだけで簡単に設定できます。
5. グループにまとめてフィルタを適用する方法
複数のページに同じフィルタを適用する場合、一つ一つのルートに設定するのは面倒です。そんな時は、ルートグループという機能を使うと便利です。
ルートグループを使えば、関連するページをまとめて、一度にフィルタを適用できます。例えば、管理画面に関連する全てのページに認証チェックを適用したい場合、次のように書きます。
<?php
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->get('/', 'Home::index');
$routes->get('/login', 'Auth::login');
$routes->post('/login', 'Auth::authenticate');
// 管理画面のルートグループに認証フィルタを適用
$routes->group('admin', ['filter' => 'auth'], function($routes) {
$routes->get('dashboard', 'Admin::dashboard');
$routes->get('users', 'Admin::users');
$routes->get('settings', 'Admin::settings');
$routes->post('users/delete/(:num)', 'Admin::deleteUser/$1');
});
このコードでは、adminというプレフィックス(接頭辞)を持つ全てのページに対して、authフィルタが自動的に適用されます。つまり、/admin/dashboard、/admin/users、/admin/settingsなどの全てのページで認証チェックが行われます。
グループ化することで、コードが見やすくなり、管理もしやすくなります。新しい管理画面のページを追加する際も、グループの中に書くだけで自動的に認証チェックが適用されます。
6. セッションを使ったログイン状態の管理
フィルタで認証チェックを行うには、ユーザーがログインしているかどうかの情報を保存しておく必要があります。その際に使うのがセッションという機能です。
セッションとは、ユーザーがウェブサイトを訪問している間、そのユーザー固有の情報を一時的に保存しておく仕組みです。例えるなら、お店で渡される「会員証」のようなもので、その会員証があれば「この人は会員だ」と識別できます。
ログイン処理が成功したら、セッションにisLoggedInという値を保存します。そして、フィルタではこの値が存在するかどうかをチェックすることで、ログイン状態を判定します。
実際のログイン処理のコントローラーでは、次のようにセッションに値を保存します。ユーザー名やパスワードが正しければ、セッションに情報を記録し、ダッシュボードページへリダイレクトします。
7. フィルタの実行タイミングと使い分け
CodeIgniterのフィルタには、beforeとafterという2つのメソッドがあります。これらは、コントローラーの実行前と実行後に処理を挟み込むためのものです。
beforeメソッドは、コントローラーが実行される前に動作します。認証チェックや入力値の検証など、「ページを表示する前に確認したいこと」を書きます。もしここで問題があれば、コントローラーの実行をキャンセルして、別のページへリダイレクトすることもできます。
afterメソッドは、コントローラーが実行された後に動作します。レスポンスの内容を加工したり、ログを記録したりする際に使います。例えば、出力されるHTMLに共通のヘッダーやフッターを追加したい場合などに便利です。
認証チェックの場合は、ページを表示する前にログイン状態を確認する必要があるため、beforeメソッドを使います。afterメソッドは今回の認証フィルタでは使用しませんが、他の用途で活用できることを覚えておきましょう。
8. フィルタで特定のメソッドだけを除外する方法
時には、コントローラーの中の一部のメソッド(処理)だけフィルタを適用したくない場合があります。例えば、ユーザー管理のコントローラーで、「一覧表示」と「編集」には認証が必要だけど、「登録フォーム」は誰でも見られるようにしたい、というケースです。
そんな時は、Filters.phpファイルの$filters配列を使って、細かく制御できます。特定のコントローラーの特定のメソッドにだけフィルタを適用する、または除外する設定が可能です。
また、ルート設定でexceptオプションを使う方法もあります。これを使えば、「このコントローラー全体に認証フィルタを適用するけど、この処理だけは除外する」という設定ができます。柔軟な認証制御を実現するために、これらの機能を組み合わせて使いましょう。
9. エラーハンドリングとユーザー体験の向上
フィルタで認証チェックを実装する際は、単にログインページへリダイレクトするだけでなく、ユーザー体験を考慮した実装が大切です。ユーザー体験とは、ウェブサイトを使う人がどれだけ快適に操作できるか、という視点のことです。
例えば、ログインしていない状態で管理画面にアクセスしようとした場合、ただログインページへ飛ばすだけでなく、「ログインが必要です」というメッセージを表示すると親切です。また、ログイン後に元々アクセスしようとしていたページへ自動的に戻る機能も、ユーザーにとって便利です。
フィルタの中でsession()->setFlashdata('message', 'ログインしてください');のようにフラッシュデータを使えば、一度だけ表示されるメッセージを簡単に実装できます。フラッシュデータとは、次のページ読み込み時に一度だけ表示され、その後自動的に削除されるデータのことです。
さらに、リダイレクト前に現在のURLをセッションに保存しておけば、ログイン成功後にそのURLへ戻すことができます。このような細かい配慮が、使いやすいウェブアプリケーションを作る上で重要になります。
10. フィルタのテストとデバッグ方法
フィルタを実装したら、正しく動作するかテストすることが大切です。ログインしていない状態で保護されたページにアクセスして、ちゃんとログインページへリダイレクトされるか確認しましょう。
デバッグの際は、CodeIgniterのデバッグツールバーが便利です。これは開発中に画面の下部に表示されるツールで、実行されたフィルタやセッションの内容などを確認できます。app/Config/Boot/development.phpで有効化されていれば自動的に表示されます。
また、フィルタの中にlog_message('debug', 'AuthFilter executed');のようなログ出力を入れると、フィルタが実行されたタイミングを記録できます。ログファイルはwritable/logsフォルダに保存されるので、問題が起きた時に確認すると原因を特定しやすくなります。
セッションの値を確認したい場合は、var_dump(session()->get());を使って全てのセッション情報を表示させることもできます。開発段階では、このような手法を使って動作を確認しながら進めていくと、確実にフィルタを実装できます。