質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

5460閲覧

laravelで共通処理を別メソッドに分けて定義しただけで動作しなくなりました

YorihiroKatsuki

総合スコア70

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2016/10/06 07:46

■概要
Laravelで特定のページ(/manage)を管理者IDを持っているユーザーのみ表示出来るようにしたいと考えています。
laravelのPolicyを使って管理者IDの利用者以外がmanage.blade.phpにアクセスしようとするとTOPページ('/')にリダイレクトさせる処理を書いたのですが、アクセス制限したいページが増えたので別のメソッドに定義してそのメソッドを呼び出すようにしたところリダイレクトしなくなりました。(制限したいページが通常通り表示されてしまう)
原因、対処法等わかりましたら教えていただけると助かります!

A.最初のコード(ちゃんと動作したコード)

php

1//ProjectController.php 2 3class ProjectController 4{ 5 /* プロジェクト管理画面表示 */ 6 public function getProjectManager(){ 7 8 //①policyを使って特定ユーザー以外を'/'にリダイレクト 9 $id = \Auth::user()->id; 10 $user = User::findOrFail($id); 11 if (Gate::denies('display',$user)) { 12 return redirect("/"); 13 } 14 15 //②projectsテーブルからidとtitleを全て取得 16 $keys = ['id','title']; 17 $projects = $this->project->getProjectInfo($keys); 18 19 //③取得したデータと一緒にviewにリターン 20 return view('manager.manage')->with('projects',$projects); 21 22 } 23}

php

1//UserPolicy.php 2 3class UserPolicy 4{ 5 //userのidが2の場合trueを返す 6 public function display(User $user){ 7 return $user->id == 2; 8 } 9}

B.ProjectControllerのgetProjectManager()メソッド内のアクセス制限部分を別メソッドcheckManager()に分割したコード(UserPolicy.phpは変更なし)
(ちゃんと動作せずに管理画面が表示されてしまう)

php

1//ProjectController.php 2 3class ProjectController 4{ 5 /* プロジェクト管理画面表示 */ 6 public function getProjectManager(){ 7 8 //外出ししたcheckManagerメソッドを実行 9 $this->checkManager(); 10 11 $keys = ['id','title']; 12 $projects = $this->project->getProjectInfo($keys); 13 14 return view('manager.manage')->with('projects',$projects); 15 16 } 17 18 public function checkManager(){ 19 //①policyを使って特定ユーザー以外を'/'にリダイレクト 20 $id = \Auth::user()->id; 21 $user = User::findOrFail($id); 22 if (Gate::denies('display',$user)) { 23 return redirect("/"); 24 } 25 } 26} 27

Aのコードだとちゃんとリダイレクトされるのですが、Bのコードだとリダイレクトされずに制限したいはずのページが表示されてしまいます。

■原因調査過程
Bのコードにてexit()を使って調べたのですが、どうも、
if(Gate::denies('display',$user)){}の中までは処理が進んでいるようで、中身を以下のように記述すると、ページにはaと表示されます。

php

1if(Gate::denies('display',$user)){ 2 echo 'a'; 3 exit(); 4 return redirect("/"); 5}

なのでreturn redirect("/")の部分がちゃんと効いていないと思います。
ただ、同じProjectController.php内でメソッドとして外出ししただけでredirectが効かなくなる理由が全くわかりません。
もしおわかりになる方がいらっしゃいましたらご教示頂けると嬉しいです。

■環境
・cloud9

どうぞ宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

直接的な要因としては、
Aのコードだとコントローラの処理(getProjectManager)の
最終的にreturnしている値がredirect("/")なのに対し、
Bのコードでは、return redirect("/")している先がgetProjectManager()メソッドであり、
そのgetProjectManager()メソッドの最終的なreturnしている値では無いからですね。

redirect()自体は、実行すれば即座にリダイレクトされるというものではなく、
RedirectResponseクラスのインスタンスを作成するものなので、実行するだけでは効果が無いです。

投稿2016/10/06 08:23

Archsted

総合スコア452

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Archsted

2016/10/06 08:31

具体的な解決策は記述しませんでしたが、例えば権限不足だったらそれに応じたエラーを発生させて Exceptions/Handler.php の中で拾ってリダイレクトする、チェック自体をmiddlewareの中で行う、ポリシークラスを利用するなどという方法もあります。
YorihiroKatsuki

2016/10/06 11:19

ありがとうございます! なるほど、getProjectManager()にreturnしていることになるんですね。 とても解りやすい解説ありがとうございました!
guest

0

ベストアンサー

以下のように修正してみてください。

php

1class ProjectController 2{ 3 /* プロジェクト管理画面表示 */ 4 public function getProjectManager(){ 5 6 //外出ししたcheckManagerメソッドを実行 7 // $this->checkManager(); 8 if ($this->checkManager()) { 9 return redirect("/"); 10 } 11 12 $keys = ['id','title']; 13 $projects = $this->project->getProjectInfo($keys); 14 15 return view('manager.manage')->with('projects',$projects); 16 17 } 18 19 public function checkManager(){ 20 //①policyを使って特定ユーザー以外を'/'にリダイレクト 21 $id = \Auth::user()->id; 22 $user = User::findOrFail($id); 23 24 // if (Gate::denies('display',$user)) { 25 // return redirect("/"); 26 // } 27 return Gate::denies('display',$user); 28 } 29}

メソッドとして外出ししただけでredirectが効かなくなる理由

は、checkManager()メソッド内でreturn redirect("/");を呼び出しているためです。

すると、制限すべきユーザーがアクセスしてきた際でもgetProjectManager()メソッドの処理が中断しないため、
結局 最終行のreturn view('manager.manage')->with('projects',$projects);が呼び出されてしまいます。

投稿2016/10/06 08:25

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YorihiroKatsuki

2016/10/06 11:18

ありがとうございます! 無事動作しました。 具体的なコードまで提示して頂き助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問