Laravel5で社内専用サイト(6-4)

さて、前回までで基本的なデータベースは完成しました。尚、UserとRoleの関連づけは本サイトでは、ご紹介していませんが、そんなに難しくないと思いますので、各自で作成してください。※Userの修正ページでロールのリストからRole_idを選択するように作成すればいいと思います。

まず、ACL(アクセスコントロールリスト)ですが、認証のauthも兼ねて作成するのも1つですが、authとは、別で作成する方法を考えてみたいと思います。ですので、アクセス制限するページには、$this->middleware(‘auth’)の後に、$this->middleware(‘acl’)と入力します。

こうすれば、$this->middleware(‘acl’,[‘only’=>[‘getDelete’,’postDelete’]])とすることで、削除用のメソッド以外には、一般的なログインユーザーがアクセスすることができるようになります。

Aclミドルウエアの作成

まず、コマンドプロンプトから下記を入力します。

php artisan make:middleware WinAcl

app/Http/MiddlewareにWinAcl.phpファイルが生成されました。

そして、生成されたファイルを下記のように修正します。

app/Http/Middleware/WinAcl.php

<?php namespace App\Http\Middleware;
use Closure;
 use Illuminate\Contracts\Auth\Guard;
class WinAcl
 {
 protected $auth;
 protected $role;
 /**
 * 新しいフィルターインスタンス
 *
 * @param Guard $auth
 * @return void
 */
 public function __construct(Guard $auth)
 {
 $this->auth = $auth;
 $this->role = $auth->user()->role;
 }
/**
 * 送られてきたリクエストの処理
 *
 * @param \Illuminate\Http\Request $request
 * @param \Closure $next
 * @return mixed
 */
 public function handle($request, Closure $next)
 {
 //アドミンならスルーする(次のリクエストへ)
 if($this->role->name == 'admin')
 {
 return $next($request);
 }
 //パーミッション不可なら
 if(!$this->allow($request)){
 return back()->withWarning('<div class="alert alert-danger">アクセス権限がありません</div>');
 }
 //パーミッション可なら次のリクエストへ
 return $next($request);
 }
 /**
 * URIの取得
 *
 * @param \Illuminate\Http\Request $request
 * @return boolean
 */
 private function getUri($request)
 {
 //URIのパスを取得
 $path=$request->path();
 //取得したパスを/で区切ってitems配列に代入
 $items=explode('/', $path);
 //配列の数が2以上なら
 if(count($items) > 1):
 $controller=$items[0];
 $action=$items[1];
 //配列の数が1以下なら
 else:
 $controller=$items[0];
 $action='index';
 endif;
 $uri=$controller.'/'.$action;
 return $uri;
 }
 /**
 * パーミッションの検査
 *
 * @param \Illuminate\Http\Request $request
 * @return boolean
 */
 private function allow($request)
 {
 //パーミッションのコレクションを取得
 $permissions=collect($this->role->permissions->lists('name'));
 //権限が無ければ
 if($permissions->isEmpty()):
 return false;
 else:
 //現在のURIを取得
 $current_uri=$this->getUri($request);
 //現在のURIとパーミッションを比較
 if($permissions->contains($current_uri)):
 return true;
 endif;
 endif;
 return false;
 }
 }
  • 17行目:ログインしていない状態だとエラーになりますので、必ずauthミドルウエアと併用します。
  • 46-63行目:まず最初に、現在のURIを取得するためのgetUri()メソッドを作成しました。path()メソッドで取得したURIをいったん、’/’で区切って、配列に分割し、分割した配列の1番目と2番目だけを再構築します。
  • 70-86行目:allow()メソッドでは、ロールが取得しているパーミッション名のリストを作成し、空ならfalseを返し、空でなければ、上記のgetUri()メソッドで取得した現在のURIが、パーミッション名のリストの中に含まれていれば、trueを返し、含まれていなければ、falseを返します。
  • 26-39行目:まず、現在のアクセスユーザーのロール名が’admin’なら、このWinAclミドルウエアは、無視して、次のリクエストへ移ります。次に、上記のallow()メソッドで、パーミッションを検査し、不可なら、メッセージとともに元のページへリダイレクトし、パーミッションが可なら、次のリクエストへ移ります。

そして、このWinAclをMiddlewareとして使用するために、kernel.phpに登録します。

app/Http/Kernel.php

protected $routeMiddleware = [
 'auth' => \App\Http\Middleware\Authenticate::class,
 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
 'acl' => \App\Http\Middleware\WinAcl::class, //ここを追加します。
 ];

最後に、アクセス制御をするコントローラのコンストラクターに下記のようにauthの後に、登録します。

public function __construct()
 {
 $this->middleware('auth');
 $this->middleware('acl',['except'=>['getIndex','getView']]);
 }

これで、コントローラのアクションごとにパーミッションを設定することができます。以前は、Admin専用のコントローラを作成していましたが、これで、専用のコントローラを作成しなくても、アクセスコントロールすることができるようになりました。

本日は、以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ