速習Larave3(その10)、ルートの保護とエラーページ
タグ: Laravel3
せっかく認証を取り入れましたが、上手く活用していません。十分に活用しましょう。
- ソース:github
Webアプリでなぜ認証が必要かと言えば、特定のページは一般の人に見せたくないからです。ルートを保護するという事ですね。
Laravelでログインしている人だけ、特定のルートのページを使用できるようにするには、auth
フィルターを使用します。
では、どのルートを保護すれば良いのでしょうか?今まで作成した中でちょっと考えてみましょう。
するとどうやら、削除と追加/更新を保護すれば良いようです。勝手に記事を消されたり、中身を書き換えられたり、むふふな記事を大量に書かれては、困ってしまいます。
とりあえず削除のルートだけに入れてみましょう。
// 記事削除 // フォーム表示 Route::get('/post/delete/(:num)', array( 'as' => 'post-delete', 'before' => 'auth', 'uses' => 'post@delete' )); // フォーム処理 Route::post('/post/delete/(:num)', array( 'as' => 'post-delete', 'before' => 'csrf|auth', 'uses' => 'post@delete' ));
これで良し。フォーム処理のルートに対し、beforeフィルターを2つ指定しています。その時は縦棒で区切って指定します。伝統的にフィルターは縦棒でつなげるものですからね。
しかしまあ、もうちょっと工夫してかけます。とりあえず、ルートの定義の部分をご覧ください。
/* * ルーティング定義 */ // トップページ:一覧表示 Route::get('/', array( 'as' => 'post-index', 'uses' => 'post@index' )); // 記事表示 Route::get('/post/(:num)', array( 'as' => 'post-show', 'uses' => 'post@show' )); // ログイン Route::get('/login', array( 'as' => 'login', 'uses' => 'auth@login' )); Route::post('/login', array( 'as' => 'login', 'before' => 'csrf', 'uses' => 'auth@login' )); // ログアウト Route::get('/logout', array( 'as' => 'logout', 'uses' => 'auth@logout' )); // ユーザー認証が必要な管理者領域 Route::group(array( 'before' => 'auth' ), function() { // 記事追加/編集 // フォーム表示 Route::get('/post/edit/(:num?)', array( 'as' => 'post-edit', 'uses' => 'post@edit' )); // フォーム処理 Route::post('/post/edit/(:num?)', array( 'as' => 'post-edit', 'before' => 'csrf', 'uses' => 'post@edit' )); // 記事削除 // フォーム表示 Route::get('/post/delete/(:num)', array( 'as' => 'post-delete', 'uses' => 'post@delete' )); // フォーム処理 Route::post('/post/delete/(:num)', array( 'as' => 'post-delete', 'before' => 'csrf', 'uses' => 'post@delete' )); });
同じフィルターを適用したいルートはグループにまとめられます。今回は認証が必要なルートをグループ化することで、ルートも読みやすくなりました。そう、可読性も大切ですよ。
これできちんと動作するか確認してください。トップページから、ログインしている時としていない時の両方で、削除と更新のリンクをクリックしてください。
auth
フィルターの定義も同じroutes.phpの中で行われています。
Route::filter('auth', function() { if ( Auth::guest() ) return Redirect::to_route('login') ->with('message', 'ログインが必要です。'); });
少し変えてあります。デフォルトのコードにメッセージを付けてリダイレクトするようにしています。なにせ、元々のコードは黙ってログインページにリダイレクトするだけですからね。
あと、Redirect::to
をRedirect::to_route()
に変更しました。to
はURLやURIに対して使用します。to_route
はルートの名前を指定します。せっかく名前をルートにつけているのですから、使わなくちゃ損ですよ。
何に役に立つかって?例えばこの場合でしたら、ログインへのURIはlogin
で分かりやすですよね。でも例えばsuper-login-48
などに変えると、このURIを知っている人しかログインできなくなりますよね。ログインのURIが分かっているとチャレンジする不届き者やら出てきますからね。ルート名を指定しておけば、そうしたURIの変更時にアチラコチラのコードをいじる必要が無くなるわけです。ルートの定義のURIパターンだけを変更すれば済みます。
あと新しい事柄は、認証のチェックで使用されている'Auth::guest()'です。これはログインしていない時にtrueになります。
これできちんと動作するか確認してください。トップページから、ログインしている時としていない時の両方で、削除と更新のリンクをクリックしてください。
よしよし。上手く動作していますね。けど、ちょっと引っかかります。よく考えたら、ログインしていない人にリンクを見せなきゃ、もっと良いですよね。
これは一覧ページのビューの変更だけで、可能ですよ。index.blade.php
を修正してください。
@layout('template') @section('title') 一覧表示 @endsection @section('content') <style> .pagination li { display: inline; margin: 0 5px; } </style> <table> <tr> <th>タイトル</th> <th>作成日</th> @if( Auth::check() ) <th>更新</th> <th>削除</th> @endif </tr> @foreach($posts as $post) <tr> <td>{{ HTML::link_to_route('post-show', $post->title ,array($post->id)) }}</td> <td>{{ $post->created_at }}</td> @if( Auth::check() ) <td>{{ HTML::link_to_route('post-edit', '✜', array($post->id)) }}</td> <td>{{ HTML::link_to_route('post-delete', '✖', array($post->id)) }}</td> @endif </tr> @endforeach </table> {{ $link }} @endsection
Auth::check()
を使用して、ログインしている場合のみ、表示するように変更しました。このメソッドはAuth::guest()
の逆でして、ログインしている場合のみtrueになります。
これで一覧ページを見てください。ログインしていないときはポスト名と作成日時が表示され、ログインすると更新、削除が表示される便利な一覧ページになりました。CMSのようですね。
せっかく、routes.phpを開いているので、もうひと工夫しましょう。エラーページです。デフォルトのエラーページは英語ですし、しかもデザインが通常のページと異なっています。みっともないですね。これをどうにかしましょう。
元々のエラーページはviews/error
フォルダーの下に、ステータスコードと同じ名前のPHPファイルに記述されています。
そして、エラー時の処理はroutes.php内で記述されており、変更可能です。通常のビューページと同じように作成可能です。まず、404エラーページを作成しましょう。
views/error/404error.blade.php
を作成してください。
@layout('template') @section('title') 404 ページが見つかりません @endsection @section('content') <h2>404エラー</h2> <h3>ページが見つかりません。</h3> <p>お探しのページが見つかりません。</p> <p>URLを指定した場合は、間違っていないかご確認ください。</p> @endsection
ご覧の通り。Bladeだって使えちゃいます。内容は短めですよ。お好きに工夫してください。
ビューを出力しているだけですが、元々のエラーステータスコードはそのまま404で送られます。全くLaravelは苦労いらずですね。
あと、500ページは皆さんにお任せします。お好きに作成してください。エラー処理も修正する必要があることをお忘れなく。