我是 cakephp 的新手,我正在尝试从头开始构建一个应用程序。我正在阅读手册,也做了教程。
现在我面临一个关于授权的问题:如何允许用户执行操作(编辑、删除、...),但前提是这是他们自己的事情(发布、事件、...),使用 ActionsAuthorize 和 ControllersAuthorize同时。也许这是一个愚蠢的问题,但作为一个新手,我觉得我错过了一些东西。
如果应用程序更简单,只使用 ControllersAuthorize (isAuthorized()) 就足够了,但我发现 ActionsAuthorize 非常有用。
按照教程(博客)中的示例,每个帖子都有一个作者(用户)并属于一个个人资料(作者,管理员,编辑器,...),一般用户可以编辑帖子($this->Acl->allow ('author','controllers/Posts/edit')) 但只有他们自己的帖子。
到目前为止,我有以下代码:
//User Model
public $actsAs = array('Acl' => array('type' => 'both'));
public $belongsTo = array(
'Profile' => array(
'className' => 'Profile',
'foreignKey' => 'profile_id'
)
);
//saving the aro alias => username
public function aftersave($created) {
if($created) {
$this->Aro->save(array('alias'=>$this->data[$this->alias]['username']));
}
}
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['profile_id'])) {
$profileId = $this->data['User']['profile_id'];
} else {
$profileId = $this->field('profile_id');
}
if (!$profileId) {
return null;
} else {
return array('Profile' => array('id' => $profileId));
}
}
//Profile Model
public $actsAs = array('Acl' => array('type' => 'both'));
public function parentNode() {
return null;
}
//savin the aco alias => name
public function aftersave($created) {
if($created) {
$this->Aro->save(array('alias'=>$this->data[$this->alias]['name']));
}
}
//Post Model
public function isOwnedBy($post, $user) {
return $this->field('id', array('id' => $post, 'user_id' => $user)) === $post;
}
//Post Controller
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('index');
}
public function isAuthorized($user) {
// All registered users can add posts
if ($this->action === 'add' && isset($user)) {
return true;
}
// The owner of a post can edit and delete it
if (in_array($this->action, array('edit', 'delete'))) {
$postId = $this->request->params['pass'][0];
if ($this->Post->isOwnedBy($postId, $user['id'])) {
//after knowing if the post is owned by the user check ACL
return $this->Acl->check($user['profile_id'],$this->Acl->aco,$this->action);
}
}
return parent::isAuthorized($user);
}
//AppController
public $components = array(
'Acl',
'Session',
'Auth' => array(
'authenticate' => array('Blowfish'),
'authError' => 'You are not allow to perform this action, please login',
'loginRedirect' => array('controller' => 'users', 'action' => 'login'),
'logoutRedirect' => array('controller' => 'posts', 'action' => 'index')
)
);
public function isAuthorized($user) {
// Only admins can access admin functions
if (isset($user['profile_id']) && isset($this->request->params['admin'])) {
return (bool)($user['profile_id'] === '1');
}
// Admin can access every action
if (isset($user['profile_id']) && $user['profile_id'] === '1') {
return true;
}
return false;
}
public function beforeFilter() {
$this->Auth->authorize = array('Controller');
$this->Auth->allow('display');
}
// The owner of a post can edit and delete it
if (in_array($this->action, array('edit', 'delete','view'))) {
$postId = $this->request->params['pass'][0];
if ($this->Post->isOwnedBy($postId, $user['id'])) {
return $this->Acl->check($user['profile_id'],$this->Acl->aco,$this->action);
}
}
return parent::isAuthorized($user);
}
所以我的问题是我是否以我在 PostController:isAutorized() 中使用它的方式正确使用了授权:首先检查用户是否拥有该帖子,然后检查用户是否允许该操作。是另一种方式吗?这种方式好不好?有更好的方法吗?我错过了什么吗?
非常感谢你!