2012-04-27 60 views
2

我有例如表数据库:在Symfony中为用户提供安全页面的最佳方法?

News: 
id | user_id | title | body 

和CRUD:

public function executeIndex(sfWebRequest $request) 
public function executeNew(sfWebRequest $request) 
public function executeShow(sfWebRequest $request) 
public function executeCreate(sfWebRequest $request) 
public function executeEdit(sfWebRequest $request) 
public function executeUpdate(sfWebRequest $request) 
public function executeDelete(sfWebRequest $request) 
protected function processForm(sfWebRequest $request, sfForm $form) 

如何是安全这一目标的最佳方法是什么? 我想用户可以编辑,更新删除只有自己新闻。 我可以做到这一点 - 获取当前的ID用户,并与新闻和下一次重定向中的user_id进行比较。也许我可以用preExecute或yaml文件做到这一点?

+0

只创建自己的新闻吗?这听起来是错误的......或者任何人都可以创建或授权的用户,或一些子用户。 – devdRew 2012-04-27 09:33:38

+0

对不起 - 更新,而不是创造 – 2012-04-27 10:04:30

回答

4

我用来做这样的事情。

我选择与方法can($what, Doctrine_Record $with)扩展(在应用程序li​​b目录myUser.class.php)用户类,也宣告几种类型的更新类型,如:常量UPDATE = 'update';等人,以同样的方式。

之后,在preExecute()我已经检索了当前请求的对象,在你的情况 - 新闻对象,并呼吁if (!$this->getUser()->can(myUser::UPDATE, $news)) { /* redirect or whatever */ }

正如你所看到的,它很容易阅读和maintanable。

这样,你把所有访问逻辑于一身,方法 - can(),在那里你可以指定你需要的任何逻辑。

希望,可以帮助你。

对于你的榜样,can()方法是这样的:

switch(get_class($with)) 
{ 
    case 'News': 
     if ($with->getUserId() != $this->getProfile()->getId()) // Assuming that getProfile() gives me a User class which News record is referenced 
     { 
      switch ($what) 
      { 
       case self::UPDATE: 
        return false; 
       case self::DELETE: 
        return false; 
      } 
     } 
     else 
     { 
      return true; // The user is owner - he can do whatever he want. 
     } 
     break; 
    default: 
     return false; // or true, don't know what you need 
} 
+0

我想你应该反转参数'can'(在功能,或在通话) – j0k 2012-04-27 09:38:34

+0

感谢,+1。我正在寻找其他解决方案 – 2012-04-27 10:05:01

+0

好的,我找到了更好的解决方案,请用它更新你的问题。提前致谢。 – devdRew 2012-04-27 12:10:22

0

我也大同小异。但我没有扩展sfUser类。我使用了symfony的过滤器链http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer#chapter_06_filters,并编写了我自己的SecurityFilter,它能够解析路由配置。

我添加了一个选项,以我的routing.yml

contact_list: 
    url: /contacts/:usergroup 
    param: { module: contacts, action: index } 
    options: { securityManager: UsergroupListSecurityManager } 

的例如特定的路由:SecurityFilter类现在使用UsergroupListSecurityManager的实例来找出它是否被允许显示页面。因此我能够设置默认的“securityManager”并在特定的路由上定义任何特定的“securityManagers” - 我还能够在不同的路由和其他上下文(创建上下文菜单或工具栏)中重用一些“securityManager”。

相关问题