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

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

新規登録して質問してみよう
ただいま回答率
85.50%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

2回答

2822閲覧

cakephp3 フォーム認証(サイト全体認証から階層認証に変えたい場合)

holic

総合スコア134

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

1クリップ

投稿2017/07/22 09:06

編集2017/07/23 04:43

###前提・実現したいこと
cakephpを勉強中のものです。本当に初歩なことだと思いますがご教示いただけましたら幸いです。
フォーム認証を作成しました。

AppController.phpのinitializeメソッド記述

php

1{ 2 parent::initialize(); 3 $this->loadComponent('Flash'); 4 //認証 5 $this->loadComponent('Auth',[ 6 'authenticate' => [ 7 'Form' => [ 8 'fields' => [ 9 'username' => 'email', 10 'password' => 'password' 11 ] 12 ] 13 ], 14 'loginAction' => [ 15 'controller' => 'Users', 16 'action' => 'login' 17 ] 18]); 19}

Usersコントローラーに、loginアクションを追加。

php

1/** 2 * ログインページ 3 * @return type 4 */ 5public function login() 6{ 7 if($this->request->is('post')){ 8 $user = $this->Auth->identify(); 9 if($user){ 10 $this->Auth->setUser($user); 11 return $this->redirect($this->Auth->redirectUrl()); 12 } 13 $this->Flash->error('ユーザー名かパスワードが間違い'); 14 } 15}

Template\Users\login.ctp

php

1<h1>Login</h1> 2<?= $this->Form->create() ?> 3<?= $this->Form->input('email') ?> 4<?= $this->Form->input('password') ?> 5<?= $this->Form->button('Login') ?> 6<?= $this->Form->end() ?>

これでサイト全体には問題なくログイン認証が成功できました。

###発生している問題・エラーメッセージ

AppController.phpのinitializeの記述ですが、AppController.phpに書いたことにより、全てのページにログイン認証がかかりました。
例えば、photosという階層直下にだけ認証が欲しい場合はどうしたら良いのかなと考えて、
PhotosController.phpにinitializeメソッドの記述を移動しました、そうしましたら/photos/のページにレンダリングをした際にログイン画面は表示はされましたが、ユーザー名とパスワード入力しましたら、
”$user = $this->Auth->identify();”がエラーですと表示されてしまいました。

イメージ説明
※もちろんサイト全体認証をかけたときにはこのエラーはでませんでした。
initializeの記述をPhotosController.phpに移動したときに発生しました。

あともう一歩な気がしますが、どのように設定したら特定の階層だけ認証ができるようになるのでしょうか。
ご教示願います。

エラーメッセージ

###補足情報(言語/FW/ツール等のバージョンなど)
cakephp3系

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

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

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

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

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

guest

回答2

0

認証するUsersControllerがAuthコンポーネントをロードしていないので、$user = $this->Auth->identify();でエラーが発生しています。なので、UsersControllerでもAuthロードすればエラーは回避できると思います。

ただし、UsersControllerとPhotosControllerの両方でAuthの設定を書くのはコードが重複してしまいますので、AppControllerでコントローラに応じて、Authをロードするコードを書くと良いかとおもいます。($this->nameでどのコントローラかは判断できます)

php

1if ($this->name == 'Users' || $this->name == 'Photos') { 2 $this->loadComponent('Auth'); 3}

なお、認証を必要としないページにおいても、認証ユーザの情報(現在ログイン中のユーザ名など)を表示したいのであれば、全ページでAuthをロードする必要があります。その場合、rikさんの回答のように$this->Auth->allow();を使って認証必要の有無を設定する方法がよいでしょう

投稿2017/07/23 00:21

編集2017/07/23 00:44
popobot

総合スコア6586

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

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

holic

2017/07/23 04:59

UsersController.phpにもAuthコンポーネントが必要だったとは全く見落としておりました。ご指摘いただけて誠にありがとうございます。 $this->nameでどのコントローラーか判断できるのかも初めて知りました、今後このif文の使用頻度は大きそうです。 icchiiさんの解答は大変勉強になります、(全体認証のやり方に補足もしていただけておりますし、より理解は深まりました)、 本当はお二方にベストアンサーをつけたいのですが今回はrikさんにベストアンサーをさせていただきます。 他の方のcakephpの質問に対して icchiiさんが的確な回答をされているのをいつも見ております、また今後も私から質問させていただくことがあると思いますがその際はよろしくお願いいたします。
popobot

2017/07/23 05:27

お役に立てて良かったです。そうですねallow()を使う方法が一般的で自分もいいと思います。
guest

0

ベストアンサー

特定の階層だけ認証させるのではなく、
全体に認証を掛けつつ、特定の階層以外を認証解除する方法は以下の通りですがいかがでしょうか?

php

1// すべてのアクションを許可 2$this->Auth->allow(); 3 4// index アクションのみ許可 5$this->Auth->allow('index'); 6 7// view と index アクションのみ許可 8$this->Auth->allow(['view', 'index']);

使用例:

php

1public function beforeFilter(Event $event) { 2 parent::beforeFilter($event); 3 $this->Auth->allow(); 4}

コントローラに記述します。記述したコントローラ内では認証解除状態となります。

投稿2017/07/22 13:39

rik

総合スコア1151

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

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

holic

2017/07/23 04:42 編集

ご回答していただきましてありがとうございます。検索してみましてもこの手法がcakephpでは一般的な手法なのだと理解しました。 先達の方々に従いこちらの手法で行きたいと考えております。 補足で質問させてください。 public function beforeFilter(~ $this->Auth->allow(); この記述は各controller.phpで記述する認識で良いのでしょうか。 今回の使用例でしたら、AppController.phpに認証かけて、PhotosController.phpは特に触らずで、認証をかけたくないParentsController.phpに記述するという使用方法でよろしいのでしょうか。 もう一点確認点として もし各コントローラーで記述ができるのでしたら ParentsController.phpの場合は $this->Auth->allow('index'); ChildsController.phpの場合は $this->Auth->allow(['view', 'index']); と認証領域を制御できるという理解で問題ないでしょうか。
holic

2017/07/24 17:35

local環境で試してみました。 use Cake\Event\Event; を付与させることで問題なく動きました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問