我正在努力研究保护用户数据的最佳方法。示例:应用程序有一个"widgets"表,每个用户可以根据需要拥有任意多个"widgets"。应用程序通过'userId'列标识'widgets',该列引用了登录用户的ID。
目前最好的方式,我已经能够确保小部件数据被访问,如果通过覆盖fetchAll()方法与我自己的模型,并添加在WHERE userId = X之前传递参数给parent::fetchAll()像这样:
class Model_Widgets extends Zend_Db_Table_Abstract {
protected $_name = 'widgets';
/**
* Abstracted function to ensure data security
* Adds in a WHERE to the SELECT to check if this user is the datas owner
*
* @see Zend_Db_Table_Abstract::fetchAll()
*/
public function fetchAll($where = null, $order = null, $count = null, $offset = null)
{
// Handle the additional security check
$userId = 'userId = ' . Model_Users::getUser()->id;
// Merge the WHERE userId statement with the rest
if($where)
{
if(is_array($where))
$where[] = $userId;
else
$where = array($where, $userId);
}
else
$where = $userId;
return parent::fetchAll($where, $order, $count, $offset);
}
这个方法工作得很好,但我不禁认为必须有一个更好的方法,我最近发现$_rowClass,但我仍然不确定我理解这个概念。如果重写具体函数是应用这些安全检查的唯一方法,是否有一种方法可以重写它们一次,而不是在每个模型中(可能通过助手)重写它们,然后简单地向每个需要根据行检查用户的模型添加如下函数:
public function fetchAll(...)
{
return SecurityCheckHelper::fetchAll(...);
我希望这是有意义的,在现实中,我所要做的就是确保用户不能访问其他用户的数据通过在URL等玩ID。由于人
目前最好的方式,我已经能够确保小部件数据被访问,如果通过覆盖fetchAll()方法与我自己的模型,并添加在WHERE userId = X之前传递参数给父::fetchAll()
你真的应该对Zend_Db_Table_Abstract
的所有函数都这样做,因为这可能会导致一些讨厌的bug。
为什么不创建一个新的抽象基类来实现所有模型的这个特性呢?如这些安全检查,是否有一种方法可以覆盖它们一次,而不是通过一个助手在每个模型中,然后简单地向每个模型添加如下函数,需要根据行检查用户:
My_Db_Table_Abstract extends Zend_Db_Table_Abstract
我试图做的是确保用户不能访问其他用户的数据通过玩的ID在URL等
这是控制器的工作!
在我的项目中,我通过使用ACL和自定义断言(在我的模型中)来解决这个问题。这甚至允许您在不更改模型的情况下进行进一步修改。