初めてのLaravel 5.1 : (30) Middleware

ログインが出来るようになったので、記事の作成や編集、削除はログインしていないと実行出来ないように制限をかけたいと思います。Laravel 5 ではこれらのフィルタリングをミドルウェアの中で実行します。Laravel 4 の時はフィルターという機能だったのですが、Laravel 5 ではミドルウェアになりました。


Middleware

ミドルウェアは以下のディレクトリに格納されています。Laravel プロジェクトを作成した時点で3つのファイルが作成されています。

app/Http/Middleware/
├── Authenticate.php
├── RedirectIfAuthenticated.php
└── VerifyCsrfToken.php

Authenticate.php を見てみます。

<?php // app/Http/Middleware/Authenticate.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;

class Authenticate {

	protected $auth;

	public function __construct(Guard $auth) {
		$this->auth = $auth;
	}

	public function handle($request, Closure $next) {
		if ($this->auth->guest()) {
			// ログインしていない時
			if ($request->ajax()) {
				return response('Unauthorized.', 401);
			} else {
				return redirect()->guest('auth/login');
			}
		}

		// ログインしている時
		return $next($request);
	}
}

ポイントは handleメソッドです。ルートからコントローラのメソッドが呼び出される前に、handleメソッドが呼び出されます。handleメソッドの中で、アプリケーションの次に進むかどうかを判断しています。Authenticate.phpでは、ログインしてない時は、ログインページにリダイレクトしています。アプリケーションを次に進めるには、$nextコールバックを呼び出します。


Middlewareの登録

app/Html/Kernel.php の中でミドルウェアをシステムに登録します。

<?php // app/Http/Kernel.php
namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel {
	/**
	 * The application's global HTTP middleware stack.
	 *
	 * @var array
	 */
	protected $middleware = [
		'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
		'Illuminate\Cookie\Middleware\EncryptCookies',
		'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
		'Illuminate\Session\Middleware\StartSession',
		'Illuminate\View\Middleware\ShareErrorsFromSession',
		'App\Http\Middleware\VerifyCsrfToken',
	];

	/**
	 * The application's route middleware.
	 *
	 * @var array
	 */
	protected $routeMiddleware = [
		'auth' => 'App\Http\Middleware\Authenticate',
		'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
		'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
	];

}

ミドルウェアのエントリポイントは2つあります。

  • ミドルウェアをシステムの全HTTPリクエストに対して実行したい場合は、$middleware に登録します。
  • ミドルウェアを特定のルートに対して実行したい場合は、$routeMiddleware にキーと共に登録します。

Controller

では、実際に ArticlesController.php コントローラでミドルウェアを使用してみます。

<?php // app/Http/Controllers/ArticlesControllers.php
namespace App\Http\Controllers;

...

class ArticlesController extends Controller {
	public function __construct()
	{
		$this->middleware('auth', ['except' => ['index', 'show']]);
	}
	...
}

コンストラクタを追加して、その中でミドルウェアを使用するよう設定します。Kernel.phpの $routeMiddlewareプロパティーに設定した時のキー(auth)を引数にして、middlewareメソッドを実行します。オプション引数に’except’を指定して、ミドルウェアの対象からindexとshow を外しています。

ここで、artisan コマンドでルートを確認します。

php artisan route:list
+--------+----------+--------------------------+------------------+--------------------------------------------------------+------------+
| Domain | Method   | URI                      | Name             | Action                                                 | Middleware |
+--------+----------+--------------------------+------------------+--------------------------------------------------------+------------+
|        | GET|HEAD | articles                 | articles.index   | App\Http\Controllers\ArticlesController@index          |            |
|        | GET|HEAD | articles/create          | articles.create  | App\Http\Controllers\ArticlesController@create         | auth       |
|        | POST     | articles                 | articles.store   | App\Http\Controllers\ArticlesController@store          | auth       |
|        | GET|HEAD | articles/{articles}      | articles.show    | App\Http\Controllers\ArticlesController@show           |            |
|        | GET|HEAD | articles/{articles}/edit | articles.edit    | App\Http\Controllers\ArticlesController@edit           | auth       |
|        | PUT      | articles/{articles}      | articles.update  | App\Http\Controllers\ArticlesController@update         | auth       |
|        | PATCH    | articles/{articles}      |                  | App\Http\Controllers\ArticlesController@update         | auth       |
|        | DELETE   | articles/{articles}      | articles.destroy | App\Http\Controllers\ArticlesController@destroy        | auth       |
+--------+----------+--------------------------+------------------+--------------------------------------------------------+------------+

※ 上記の表は article に絞って表示しています。

表の1番右の Middleware 欄を見ると、auth が適用されていることが確認できます。index と show は対象外となっていることも確認できます。

これで、ログインしていない時に、記事の作成や編集、削除を使用とすると、ミドルウェアのチェックに引っ掛かり、ログインページヘリダイレクトされるようになりました。動作確認してみてください。


View

ArticlesController.phpにミドルウェアを追加したので、Viewの方もログイン状態に応じてボタンの表示制御を行うよう修正します。

記事一覧

{{-- resources/views/articles/index.blade.php --}}
@extends('layout')

@section('content')
	<h1>Articles</h1>

	<hr/>

	{{-- ログインしている時だけ表示 --}}
	@if (Auth::check())
		{!! link_to('articles/create', '新規作成', ['class' => 'btn btn-primary']) !!}
	@endif

	@foreach($articles as $article)
		...
	@endforeach
@stop

新規作成ボタンをログインしている時だけ表示するよう修正。

記事表示

{{-- resources/views/articles/show.blade.php --}}
@extends('layout')

@section('content')
	<h1>{{ $article->title }}</h1>

	<hr/>

	<article>
		<div class="body">{{ $article->body }}</div>
	</article>

	{{-- ログインしている時だけ表示 --}}
	@if (Auth::check())
		<br/>

		{!! link_to(route('articles.edit', [$article->id]), '編集', ['class' => 'btn btn-primary']) !!}

		<br/>
		<br/>

		{!! delete_form(['articles', $article->id]) !!}
	@endif
@stop

編集、削除ボタンをログインしている時だけ表示するよう修正。


Middlewareの新規作成

新規にMiddlewareを作成するには artisan コマンドを使用します。

php artisan make:middleware MyMiddleware

app/Http/Middleware/MyMiddleware.php が作成されます。

<?php namespace App\Http\Middleware;

use Closure;

class MyMiddleware {

	public function handle($request, Closure $next)
	{
		// ここで何かやります。

		return $next($request);
	}

}

まとめ

以下のことが出来るようになりました。

  • ミドルウェアの新規作成
  • ミドルウェアのシステムへの登録
  • ミドルウェアを使ってのコントローラ実行制御

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中