cakephp 3 允许用户只编辑他们的个人资料

cakephp 3 Allow user to edit only their profile

我正在用 cakephp 3 制作一个应用程序,我的用户有两个角色,管理员和学生。管理员可以访问所有内容,而学生只能访问他的个人资料。我已经完成了这部分,但我不知道如何限制学生只看他的个人资料而不是所有个人资料。例如,如果我使用用户 3 登录,这是 url http://localhost:8765/users/view/4 以查看用户 4 的个人资料,但是如果将 4 更改为 3,我可以看到用户 3 的个人资料。如何我可以解决这个问题吗?

AppController.php

class AppController extends Controller
{


    public function initialize()
    {
        $this->loadComponent('Flash');
        $this->loadComponent('Auth', [
            'authorize' => ['Controller'],
            'loginRedirect' => [
                'controller' => 'Users',
                'action' => 'index'
            ],
            'logoutRedirect' => [
                'controller' => 'Users',
                'action' => 'login'
            ]
        ]);
    }

    public function beforeFilter(Event $event)
    {
        $this->Auth->allow(['login']);
    }

    public function isAuthorized($user)
    {
    // Admin can access every action
        if (isset($user['rol']) && $user['rol'] === 'admin') {
            return true;
       }
    // Default deny
       return false;
    }
}

UserController.php

class UsersController extends AppController
{

/**
 * Index method
 *
 * @return void
 */
public function index()
{
    $this->paginate = [
        'contain' => ['Grados']
    ];
    $this->set('users', $this->paginate($this->Users));
    $this->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->Users->get($id, [
        'contain' => ['Grados', 'Clases', 'ConveniosUsuarios', 'Desvinculaciones', 'HistorialAlumnos', 'Pagos', 'Pedidos']
    ]);
    $this->set('user', $user);
    $this->set('_serialize', ['user']);
}

/**
 * Add method
 *
 * @return void Redirects on successful add, renders view otherwise.
 */
public function add()
{
    $user = $this->Users->newEntity();
    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->data);

        if ($this->Users->save($user)) {
            $this->Flash->success(__('The user has been saved.'));
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
    }
    $grados = $this->Users->Grados->find('list', ['limit' => 200]);
    $this->set(compact('user', 'grados'));
    $this->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->Users->get($id, [
        'contain' => []
    ]);
    if ($this->request->is(['patch', 'post', 'put'])) {
        $user = $this->Users->patchEntity($user, $this->request->data);
        $filename = WWW_ROOT.'files'.DS.'images'.DS.$this->request->data['id'].$this->request->data['foto']['name'];
        move_uploaded_file($this->request->data['foto']['tmp_name'],$filename);
        $user->set('foto',$filename);
        if ($this->Users->save($user)) {
            $this->Flash->success(__('The user has been saved.'));
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
    }
    $grados = $this->Users->Grados->find('list', ['limit' => 200]);
    $this->set(compact('user', 'grados'));
    $this->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->request->allowMethod(['post', 'delete']);
    $user = $this->Users->get($id);
    if ($this->Users->delete($user)) {
        $this->Flash->success(__('The user has been deleted.'));
    } else {
        $this->Flash->error(__('The user could not be deleted. Please, try again.'));
    }
    return $this->redirect(['action' => '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->Auth->allow(['logout']);
}

public function login()
{
    if ($this->request->is('post')) {
        $user = $this->Auth->identify();
        if ($user) {
            $this->Auth->setUser($user);
            if ($this->Auth->user('rol') == 'Alumno') {
                $this->redirect('users'.DS.'view'.DS.$this->Auth->user('id'));
            }else{
                return $this->redirect($this->Auth->redirectUrl());
            }
        }else{
            $this->Flash->error(__('Usario o contraseña invalidos!'));    
        }
    }
}

public function logout()
{
    return $this->redirect($this->Auth->logout());
}

public function isAuthorized($user)
{
    $userid=$this->Auth->user('id');
    $action = $this->request->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);
}
}

调试($this->request)

object(Cake\Network\Request) {
params => [
    'plugin' => null,
    'controller' => 'Users',
    'action' => 'view',
    '_ext' => null,
    'pass' => [
        (int) 0 => '4'
    ]
]
data => []
query => []
cookies => [
    'CAKEPHP' => 't8o6augt5qd0a8p3squq4kmni2'
]
url => 'users/view/4'
base => ''
webroot => '/'
here => '/users/view/4'
trustProxy => false
[protected] _environment => [
    'DOCUMENT_ROOT' => 'C:\xampp\htdocs\intranet\webroot',
    'REMOTE_ADDR' => '::1',
    'REMOTE_PORT' => '50389',
    'SERVER_SOFTWARE' => 'PHP 5.6.8 Development Server',
    'SERVER_PROTOCOL' => 'HTTP/1.1',
    'SERVER_NAME' => 'localhost',
    'SERVER_PORT' => '8765',
    'REQUEST_URI' => '/users/view/4',
    'REQUEST_METHOD' => 'GET',
    'SCRIPT_NAME' => '/index.php',
    'SCRIPT_FILENAME' => 'C:\xampp\htdocs\intranet\webroot\index.php',
    'PATH_INFO' => '/users/view/4',
    'PHP_SELF' => '/index.php',
    'HTTP_HOST' => 'localhost:8765',
    'HTTP_CONNECTION' => 'keep-alive',
    'HTTP_CACHE_CONTROL' => 'max-age=0',
    'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'HTTP_USER_AGENT' => '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' => 'gzip, deflate, sdch',
    'HTTP_ACCEPT_LANGUAGE' => 'es-ES,es;q=0.8,en;q=0.6',
    'HTTP_COOKIE' => 'CAKEPHP=t8o6augt5qd0a8p3squq4kmni2',
    'REQUEST_TIME_FLOAT' => (float) 1437761676.7461,
    'REQUEST_TIME' => (int) 1437761676,
    'HTTP_X_HTTP_METHOD_OVERRIDE' => null,
    'ORIGINAL_REQUEST_METHOD' => 'GET',
    'HTTPS' => false
]
[protected] _detectors => [
    'get' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'GET'
    ],
    'post' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'POST'
    ],
    'put' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'PUT'
    ],
    'patch' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'PATCH'
    ],
    'delete' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'DELETE'
    ],
    'head' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'HEAD'
    ],
    'options' => [
        'env' => 'REQUEST_METHOD',
        'value' => 'OPTIONS'
    ],
    'ssl' => [
        'env' => 'HTTPS',
        'options' => [
            (int) 0 => (int) 1,
            (int) 1 => 'on'
        ]
    ],
    'ajax' => [
        'env' => 'HTTP_X_REQUESTED_WITH',
        'value' => 'XMLHttpRequest'
    ],
    'flash' => [
        'env' => 'HTTP_USER_AGENT',
        'pattern' => '/^(Shockwave|Adobe) Flash/'
    ],
    'requested' => [
        'param' => 'requested',
        'value' => (int) 1
    ],
    'json' => [
        'accept' => [
            (int) 0 => 'application/json'
        ],
        'param' => '_ext',
        'value' => 'json'
    ],
    'xml' => [
        'accept' => [
            (int) 0 => 'application/xml',
            (int) 1 => 'text/xml'
        ],
        'param' => '_ext',
        'value' => 'xml'
    ],
    'mobile' => object(Closure) {

    },
    'tablet' => object(Closure) {

    }
]
[protected] _detectorCache => []
[protected] _input => ''
[protected] _session => object(Cake\Network\Session) {
    [protected] _engine => null
    [protected] _started => true
    [protected] _lifetime => '1440'
    [protected] _isCLI => false
}
}
public function isAuthorized($user)
{
    $requestedUserId=$this->request->pass[0];

    if ($user['rol']=='Admin') 
    {
        return true;
    }

    else if ($user['rol']!='Admin') 
    {

    if (!($this->request->action == 'index')) 
    {

    if($userid==$user['id']) 
    {
        return true;
    }

    }
        return false;
    }
    return parent::isAuthorized($user);
}

我终于用这个插件解决了这个问题: https://github.com/AlessandroMinoccheri/UserPermissions

// UsersController.php
public function isAuthorized($user) {

    if (in_array($this->request->action, ['edit', 'delete'])) {
      $id = (int) $this->request->params['pass'][0];
      if ($id == $user['id']) {
        return true;
      }
    }

    return parent::isAuthorized($user);
  }

// AppController.php
public function isAuthorized($user)
{
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }
    return false;
}