[Laravel 5] 筆記13 Ogres Are Like Middleware

2015-03-15

https://laracasts.com/series/laravel-5-fundamentals/episodes/16

輸入網址 經由 routes 根據規則進入 controller 之前
可能會需要先判斷是否登入 或是登入的會員是否有管理者權限
為了不要在每個需要的 method 裡都做同樣的判斷
所以需要用到 middleware 讓這些判斷可以簡化並重複使用

各 middleware 的路徑統一放在 Kernel.php
▼ app/Http/Kernel.php

class Kernel extends HttpKernel {
	// 通用的擺在這裡面 每個 controller 一定都會讀一遍
	protected $middleware = [ /* something */ ];

	// 需要依使用情況加入的放這裡
	protected $routeMiddleware = [
		// 安裝好後預設就有這些
		'auth' => 'App\Http\Middleware\Authenticate',
		'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
		'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',

		// 範例
		'manager' => 'App\Http\Middleware\RedirectIfNotAManager'
	];
}

 
使用 artisan 建立自己的 middleware (名字不限制 自己看得懂就好)

php artisan make:middleware RedirectIfNotAManager

建立的檔案如下
▼ app/Http/Middleware/RedirectIfNotAManager.php

class RedirectIfNotAManager {
    public function handle($request, Closure $next)
    {
    	// 自己建立的條件 沒通過即轉到 articles
    	if ( ! $request->user()->isATeamManager() ) {
        	return redirect('articles');
    	}
    	
        return $next($request);
    }
}

接著要在 model 檔案建立這個判斷用的 method
▼ app/User.php

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
    // 示範用 所以直接回 true    
    public function isATeamManager() {
        return true;
    }
}

 
使用 middleware 的方法有兩種
第 1 種 在 Controller 裡使用
▼ app/Http/Controllers/ArticlesController.php

class ArticlesController extends Controller {
    public function __construct()
    {
        // 所有 method 都會先經過 auth 這個 middleware
        $this->middleware('auth');

        // 只有 create 會經過 auth 這個 middleware
        $this->middleware('auth',['only' => 'create']);

        // 除了 index 之外都會先經過 auth 這個 middleware
        $this->middleware('auth',['except' => 'index']);
    }
}

第 2 種是直接在 routes 裡使用
▼ app/Http/routes.php

// 針對要使用的規則加入 middleware
Route::get('home', ['middleware' => 'auth', 'uses' => 'HomeController@index']);

// 超過兩個規則的話則用 array 放置 ( manager 即為上面建立的示範檔案 )
Route::get('foo', ['middleware' => ['auth', 'manager'], 'uses' => function(){
    return 'good day';
}]);