title: cakephp 3 Allow user to edit only their profile
body: <p>I am making a app with cakephp 3, my user have two roles, admin and student. The admin can access everything and the student just his profile. I done this part already, but i do not know how to restrict the students just to see his profiles and not all the profiles. for example, if i logged with user 3 this is the url <a href="http://localhost:8765/users/view/4" rel="nofollow">http://localhost:8765/users/view/4</a> to see the profile of user 4, but if a change the 4 with a 3, i can see the profile of user 3. how i can fix this?</p>
  
  <p><strong>AppController.php</strong></p>
  
  <pre><code>class AppController extends Controller
  {
  
  
      public function initialize()
      {
          $this-&gt;loadComponent('Flash');
          $this-&gt;loadComponent('Auth', [
              'authorize' =&gt; ['Controller'],
              'loginRedirect' =&gt; [
                  'controller' =&gt; 'Users',
                  'action' =&gt; 'index'
              ],
              'logoutRedirect' =&gt; [
                  'controller' =&gt; 'Users',
                  'action' =&gt; 'login'
              ]
          ]);
      }
  
      public function beforeFilter(Event $event)
      {
          $this-&gt;Auth-&gt;allow(['login']);
      }
  
      public function isAuthorized($user)
      {
      // Admin can access every action
          if (isset($user['rol']) &amp;&amp; $user['rol'] === 'admin') {
              return true;
         }
      // Default deny
         return false;
      }
  }
  </code></pre>
  
  <p><strong>UserController.php</strong></p>
  
  <pre><code>class UsersController extends AppController
  {
  
  /**
   * Index method
   *
   * @return void
   */
  public function index()
  {
      $this-&gt;paginate = [
          'contain' =&gt; ['Grados']
      ];
      $this-&gt;set('users', $this-&gt;paginate($this-&gt;Users));
      $this-&gt;set('_serialize', ['users']);
  }
  
  /**
   * View method
   *
   * @param string|null $id User id.
   * @return void
   * @throws \Cake\Network\Exception\NotFoundException When record not found.
   */
  public function view($id = null)
  {
      $user = $this-&gt;Users-&gt;get($id, [
          'contain' =&gt; ['Grados', 'Clases', 'ConveniosUsuarios', 'Desvinculaciones', 'HistorialAlumnos', 'Pagos', 'Pedidos']
      ]);
      $this-&gt;set('user', $user);
      $this-&gt;set('_serialize', ['user']);
  }
  
  /**
   * Add method
   *
   * @return void Redirects on successful add, renders view otherwise.
   */
  public function add()
  {
      $user = $this-&gt;Users-&gt;newEntity();
      if ($this-&gt;request-&gt;is('post')) {
          $user = $this-&gt;Users-&gt;patchEntity($user, $this-&gt;request-&gt;data);
  
          if ($this-&gt;Users-&gt;save($user)) {
              $this-&gt;Flash-&gt;success(__('The user has been saved.'));
              return $this-&gt;redirect(['action' =&gt; 'index']);
          } else {
              $this-&gt;Flash-&gt;error(__('The user could not be saved. Please, try again.'));
          }
      }
      $grados = $this-&gt;Users-&gt;Grados-&gt;find('list', ['limit' =&gt; 200]);
      $this-&gt;set(compact('user', 'grados'));
      $this-&gt;set('_serialize', ['user']);
  }
  
  /**
   * Edit method
   *
   * @param string|null $id User id.
   * @return void Redirects on successful edit, renders view otherwise.
   * @throws \Cake\Network\Exception\NotFoundException When record not found.
   */
  public function edit($id = null)
  {
      $user = $this-&gt;Users-&gt;get($id, [
          'contain' =&gt; []
      ]);
      if ($this-&gt;request-&gt;is(['patch', 'post', 'put'])) {
          $user = $this-&gt;Users-&gt;patchEntity($user, $this-&gt;request-&gt;data);
          $filename = WWW_ROOT.'files'.DS.'images'.DS.$this-&gt;request-&gt;data['id'].$this-&gt;request-&gt;data['foto']['name'];
          move_uploaded_file($this-&gt;request-&gt;data['foto']['tmp_name'],$filename);
          $user-&gt;set('foto',$filename);
          if ($this-&gt;Users-&gt;save($user)) {
              $this-&gt;Flash-&gt;success(__('The user has been saved.'));
              return $this-&gt;redirect(['action' =&gt; 'index']);
          } else {
              $this-&gt;Flash-&gt;error(__('The user could not be saved. Please, try again.'));
          }
      }
      $grados = $this-&gt;Users-&gt;Grados-&gt;find('list', ['limit' =&gt; 200]);
      $this-&gt;set(compact('user', 'grados'));
      $this-&gt;set('_serialize', ['user']);
  }
  
  /**
   * Delete method
   *
   * @param string|null $id User id.
   * @return void Redirects to index.
   * @throws \Cake\Network\Exception\NotFoundException When record not found.
   */
  public function delete($id = null)
  {
      $this-&gt;request-&gt;allowMethod(['post', 'delete']);
      $user = $this-&gt;Users-&gt;get($id);
      if ($this-&gt;Users-&gt;delete($user)) {
          $this-&gt;Flash-&gt;success(__('The user has been deleted.'));
      } else {
          $this-&gt;Flash-&gt;error(__('The user could not be deleted. Please, try again.'));
      }
      return $this-&gt;redirect(['action' =&gt; 'index']);
  }
  
  public function beforeFilter(Event $event)
  {
      parent::beforeFilter($event);
      // Allow users to register and logout.
      // You should not add the "login" action to allow list. Doing so would
      // cause problems with normal functioning of AuthComponent.
      $this-&gt;Auth-&gt;allow(['logout']);
  }
  
  public function login()
  {
      if ($this-&gt;request-&gt;is('post')) {
          $user = $this-&gt;Auth-&gt;identify();
          if ($user) {
              $this-&gt;Auth-&gt;setUser($user);
              if ($this-&gt;Auth-&gt;user('rol') == 'Alumno') {
                  $this-&gt;redirect('users'.DS.'view'.DS.$this-&gt;Auth-&gt;user('id'));
              }else{
                  return $this-&gt;redirect($this-&gt;Auth-&gt;redirectUrl());
              }
          }else{
              $this-&gt;Flash-&gt;error(__('Usario o contraseña invalidos!'));    
          }
      }
  }
  
  public function logout()
  {
      return $this-&gt;redirect($this-&gt;Auth-&gt;logout());
  }
  
  public function isAuthorized($user)
  {
      $userid=$this-&gt;Auth-&gt;user('id');
      $action = $this-&gt;request-&gt;params['action'];
      if ($user['rol']=='Admin') {
          return true;
      }else if ($user['rol']!='Admin') {
          if (in_array($action, ['edit', 'view'])) {
              return true;
          }
          return false;
      }
      return parent::isAuthorized($user);
  }
  }
  </code></pre>
  
  <p><strong>debug($this->request)</strong></p>
  
  <pre><code>object(Cake\Network\Request) {
  params =&gt; [
      'plugin' =&gt; null,
      'controller' =&gt; 'Users',
      'action' =&gt; 'view',
      '_ext' =&gt; null,
      'pass' =&gt; [
          (int) 0 =&gt; '4'
      ]
  ]
  data =&gt; []
  query =&gt; []
  cookies =&gt; [
      'CAKEPHP' =&gt; 't8o6augt5qd0a8p3squq4kmni2'
  ]
  url =&gt; 'users/view/4'
  base =&gt; ''
  webroot =&gt; '/'
  here =&gt; '/users/view/4'
  trustProxy =&gt; false
  [protected] _environment =&gt; [
      'DOCUMENT_ROOT' =&gt; 'C:\xampp\htdocs\intranet\webroot',
      'REMOTE_ADDR' =&gt; '::1',
      'REMOTE_PORT' =&gt; '50389',
      'SERVER_SOFTWARE' =&gt; 'PHP 5.6.8 Development Server',
      'SERVER_PROTOCOL' =&gt; 'HTTP/1.1',
      'SERVER_NAME' =&gt; 'localhost',
      'SERVER_PORT' =&gt; '8765',
      'REQUEST_URI' =&gt; '/users/view/4',
      'REQUEST_METHOD' =&gt; 'GET',
      'SCRIPT_NAME' =&gt; '/index.php',
      'SCRIPT_FILENAME' =&gt; 'C:\xampp\htdocs\intranet\webroot\index.php',
      'PATH_INFO' =&gt; '/users/view/4',
      'PHP_SELF' =&gt; '/index.php',
      'HTTP_HOST' =&gt; 'localhost:8765',
      'HTTP_CONNECTION' =&gt; 'keep-alive',
      'HTTP_CACHE_CONTROL' =&gt; 'max-age=0',
      'HTTP_ACCEPT' =&gt; 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
      'HTTP_USER_AGENT' =&gt; 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36',
      'HTTP_ACCEPT_ENCODING' =&gt; 'gzip, deflate, sdch',
      'HTTP_ACCEPT_LANGUAGE' =&gt; 'es-ES,es;q=0.8,en;q=0.6',
      'HTTP_COOKIE' =&gt; 'CAKEPHP=t8o6augt5qd0a8p3squq4kmni2',
      'REQUEST_TIME_FLOAT' =&gt; (float) 1437761676.7461,
      'REQUEST_TIME' =&gt; (int) 1437761676,
      'HTTP_X_HTTP_METHOD_OVERRIDE' =&gt; null,
      'ORIGINAL_REQUEST_METHOD' =&gt; 'GET',
      'HTTPS' =&gt; false
  ]
  [protected] _detectors =&gt; [
      'get' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'GET'
      ],
      'post' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'POST'
      ],
      'put' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'PUT'
      ],
      'patch' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'PATCH'
      ],
      'delete' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'DELETE'
      ],
      'head' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'HEAD'
      ],
      'options' =&gt; [
          'env' =&gt; 'REQUEST_METHOD',
          'value' =&gt; 'OPTIONS'
      ],
      'ssl' =&gt; [
          'env' =&gt; 'HTTPS',
          'options' =&gt; [
              (int) 0 =&gt; (int) 1,
              (int) 1 =&gt; 'on'
          ]
      ],
      'ajax' =&gt; [
          'env' =&gt; 'HTTP_X_REQUESTED_WITH',
          'value' =&gt; 'XMLHttpRequest'
      ],
      'flash' =&gt; [
          'env' =&gt; 'HTTP_USER_AGENT',
          'pattern' =&gt; '/^(Shockwave|Adobe) Flash/'
      ],
      'requested' =&gt; [
          'param' =&gt; 'requested',
          'value' =&gt; (int) 1
      ],
      'json' =&gt; [
          'accept' =&gt; [
              (int) 0 =&gt; 'application/json'
          ],
          'param' =&gt; '_ext',
          'value' =&gt; 'json'
      ],
      'xml' =&gt; [
          'accept' =&gt; [
              (int) 0 =&gt; 'application/xml',
              (int) 1 =&gt; 'text/xml'
          ],
          'param' =&gt; '_ext',
          'value' =&gt; 'xml'
      ],
      'mobile' =&gt; object(Closure) {
  
      },
      'tablet' =&gt; object(Closure) {
  
      }
  ]
  [protected] _detectorCache =&gt; []
  [protected] _input =&gt; ''
  [protected] _session =&gt; object(Cake\Network\Session) {
      [protected] _engine =&gt; null
      [protected] _started =&gt; true
      [protected] _lifetime =&gt; '1440'
      [protected] _isCLI =&gt; false
  }
  }
  </code></pre>