使用POST而不是GET保护CakePHP中的方法

时间:2012-02-29 21:04:35

标签: php cakephp

我想保护我的应用程序中的某些方法,例如发布,取消发布和关闭。通过保护,我不是指用户授权,而是以某种方式调用该方法的能力。

我已经考虑过使用POST而不是GET来强制调用方法,这样一个人就不能只将URL粘贴到地址中(即使我只能检查执行此操作的人的用户ID)。但是,这意味着为每个方法调用以不同的形式包装每个按钮。

或者我可以使用GUID来允许GET方法,但要确保它只允许正确的人来执行该功能。

对此有何想法?

到目前为止,我已经尝试过:

function publish($id = null)
    {
        $post = $this->Post->find('first',array('conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));

        if ($this->request->is('post') || $this->request->is('put'))
        {
            $this->Post->id = $post['Post']['id'];
            $this->Post->saveField('status', 1);
            $this->Session->setFlash('Your post has been published!');
            $this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
        }
        else
        {
            die('GET METHOD NOT ALLOWED');
        }
    }

但如上所述,这意味着此方法的链接/按钮需要采用包含对此方法的操作调用的形式。如果我有几种方法,我需要几种形式......

干杯

我想到的一种方法是允许get方法,然后检查帖子的用户ID与登录用户ID相比如下:

if ($this->request->is('get'))
        {
            if($post['Post']['user_id'] != $this->Auth->user('id'))
            {
                $this->Session->setFlash('You don\'t have permission to edit that post!');
                $this->redirect(array('controller' => 'posts', 'action' => 'index'));
            }
            else
            {
                $this->Post->id = $post['Post']['id'];
                $this->Post->saveField('status', 1);
                $this->Session->setFlash('Your post has been published!');
                $this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
            }
        }

这是好习惯吗?

3 个答案:

答案 0 :(得分:6)

(假设CakePHP 2.0在这里)

首先,不要在Post / Get检查中调用die。抛出异常,蛋糕中的异常很精彩(Exceptions):

if (!$this->request->is('get')) {
    throw new MethodNotAllowedException();
}

Cake还提供了一种在模板中生成删除(通过帖子)链接的方法。

<?php echo $this->Form->postLink('Delete',
    array('action' => 'delete', $post['Post']['id']),
    array('confirm' => 'Are you sure?'));
?>

修改(链接):postLink

这是我在Stack Overflow中的第一个答案。希望它有所帮助。

答案 1 :(得分:1)

如果您只想允许某些用户执行该功能,则听起来您需要ACL或某种形式的权限。你不会使用像你发布的那样(if($post['Post']['user_id'] != $this->Auth->user('id')))的原因是因为你最终会在你的代码库中复制很多函数中的代码。这非常草率。

但是,您只想确保以特定方式提交提交,然后使用throw error方法。你应该能够将提交保持在同一个函数中,如下所示:

public function publish($id = null) {
    if (!$id || !$this->request->is('get') || !$this->request->is('post') || !$this->request->is('put')) {
        throw new MethodNotAllowedException();
    }

    if ($this->request->is('post') || $this->request->is('put')) {
            $this->Post->id = $post['Post']['id'];
            $this->Post->saveField('status', 1);
            $this->Session->setFlash('Your post has been published!');
            $this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
    }

    if ($this->request->is('get')) {
        // perform your get request here
    }

}

答案 2 :(得分:0)

With minimal code $this->request->allowMethod('post');