【CakePHP2】「シンプルな認証と承認のアプリケーション」を細かく理解する

// app/Controller/UsersController.php

class UsersController extends AppController {
// beforeFilterで一番最初に行う処理設定、ここでは認証をしないページをAuth->allowで設定
これによって誰でもaddアクションができる
   public function beforeFilter() {
       parent::beforeFilter();
       $this->Auth->allow('add');
   }
   public function index() {
       $this->User->recursive = 0;
       $this->set('users', $this->paginate());
   }

   public function view($id = null) {
       $this->User->id = $id;
       if (!$this->User->exists()) {
           throw new NotFoundException(__('Invalid user'));
       }
       $this->set('user', $this->User->findById($id));
   }

   public function add() {
       if ($this->request->is('post')) {
           $this->User->create();
           if ($this->User->save($this->request->data)) {
               $this->Flash->success(__('The user has been saved'));
               return $this->redirect(array('action' => 'index'));
           }
           $this->Flash->error(
               __('The user could not be saved. Please, try again.')
           );
       }
   }

   public function edit($id = null) {
       $this->User->id = $id;
       if (!$this->User->exists()) {
           throw new NotFoundException(__('Invalid user'));
       }
       if ($this->request->is('post') || $this->request->is('put')) {
           if ($this->User->save($this->request->data)) {
               $this->Flash->success(__('The user has been saved'));
               return $this->redirect(array('action' => 'index'));
           }
           $this->Flash->error(
               __('The user could not be saved. Please, try again.')
           );
       } else {
           $this->request->data = $this->User->findById($id);
           unset($this->request->data['User']['password']);
       }
   }

   public function delete($id = null) {
       // Prior to 2.5 use
       // $this->request->onlyAllow('post');
//// POSTのリクエストのみ受け入れ制限
       $this->request->allowMethod('post');

       $this->User->id = $id;
       if (!$this->User->exists()) {
           throw new NotFoundException(__('Invalid user'));
       }
       if ($this->User->delete()) {
           $this->Flash->success(__('User deleted'));
           return $this->redirect(array('action' => 'index'));
       }
       $this->Flash->error(__('User was not deleted'));
       return $this->redirect(array('action' => 'index'));
   }
   public function login() {
      if ($this->request->is('post')) {
          if ($this->Auth->login()) {
              $this->redirect($this->Auth->redirect());
          } else {
              $this->Flash->error(__('Invalid username or password, try again'));
          }
      }
   }
   public function logout() {
      $this->redirect($this->Auth->logout());
   }

公式のチュートリアル を引用して、分からないところを検索して、下記にアウトプットします

$this->User->recursive = 0;

find()で関連モデルのデータを取得しない方法(joinさせない方法)

$this->paginate()

Controllerクラスの$paginate変数にページネーションの設定
Viewの中では、PaginatorHelperクラスという各ページへのリンクやページ番号の制御を行うクラスを使用しページングやソート(sort、order)を簡単に実装する

$this->User->create();
if ($this->User->save($this->request->data)) {

Model::create() は、一旦モデルの中身をリセットしてくれるメソッド
Model::create() →Model::save()
※まだ理解が曖昧だが、ここではとりあえず上記の処理を行うということだけを理解

$this->Auth->login()

   public function login() {
      if ($this->request->is('post')) {
          if ($this->Auth->login()) {
              $this->redirect($this->Auth->redirect());
          }
      }
  }

上記の公式がなんでも認証してしまうなんでやねん仕様だったので、悪戦苦闘ググりまくりスティを続けていたら


モデル名を間違えて複数名にしていたという痛恨の凡ミス


// app/Model/User.php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
// ...
public function beforeSave($options = array()) {
   if (isset($this->data[$this->alias]['password'])) {
       $passwordHasher = new BlowfishPasswordHasher();
       $this->data[$this->alias]['password'] = $passwordHasher->hash(
           $this->data[$this->alias]['password']
       );
   }
   return true;
}

beforeSave()関数はモデルのデータがバリデーションに成功した後、 データが保存される前に実行(今回の内容だとパスワードをハッシュ化)

public function beforeFilter() 

beforeFilterは常に一番最初に処理が実行されるため、各アクションを実行する前に共通処理や初期処理を記述
beforeFilterは一番はじめに呼び出されるため、Authなどのユーザー認証を行う処理やエラー内容を設定するのにも適しています。

$this->Auth->allow('index', 'view');

// app/Controller/AppController.php

    public function beforeFilter() {
       $this->Auth->allow('index', 'view');
   }

全ユーザーにindex、viewアクションにアクセス許可

// app/Controller/UsersController.php

public function beforeFilter() {
   parent::beforeFilter();
   // ユーザー自身による登録とログアウトを許可する
   $this->Auth->allow('add', 'logout');
}

parent::beforeFilter();で$this->Auth->allow('index', 'view');を共有


承認(誰が何にアクセスができるか)
悪戦したのでメモします

// app/Controller/PostsController.php
public function isAuthorized($user) {
   // 登録済ユーザーは投稿できる
   if ($this->action === 'add') {
       return true;
   }
   // 投稿のオーナーは編集や削除ができる
   if (in_array($this->action, array('edit', 'delete'))) {
       $postId = (int) $this->request->params['pass'][0];
       if ($this->Post->isOwnedBy($postId, $user['id'])) {
           return true;
       } else {
        //公式は、parent::isAuthorized($user); ですが、管理者などは設定していないので、エラーを投げます
        throw new MethodNotAllowedException('他人の投稿は編集できません');
        }
    }
}

パラメータを取得


//URL - ctrl/act/param1/param2

$this->params['pass'][0]; //param1
$this->params['pass'][1]; //param2

とりあえずこんな感じでしょうか。
現在は別モデルのテーブルからデータを表示するところでつまづいてます。

この記事が気に入ったらサポートをしてみませんか?