欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

YII的访问控制

程序员文章站 2024-03-19 13:00:58
...

在Yii为Model生成的Controller中,有一个accessRules()方法,用来限制谁可以做什么。这是涉及一个web应用的安全性的重要部分。比如有些删除和更新操作只能由管理员来完成,普通用户没有操作的权限等等,这些都需要通过accessRules()来设置。

  这是Yii默认生成的代码:

public function accessRules()
{
    return array(
        array('allow',  // allow all users to perform 'list' and 'show' actions
            'actions'=>array('list','show'),
            'users'=>array('*'),
        ),
        array('allow', // allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>array('@'),
        ),
        array('allow', // allow admin user to perform 'admin' and 'delete' actions
            'actions'=>array('admin','delete'),
            'users'=>array('admin'),
        ),
        array('deny',  // deny all users
            'users'=>array('*'),
        ),
    );
}

 在前三个规则中,其中*表示所有user,@表示已登录的user,admin是管理员的name,如果管理员有多个,你可以简单地将名字硬编码进去,就像:

array('allow', // allow harold and maude user to perform 'admin' and 'delete' actions
    'actions'=>array('admin','delete'),
    'users'=>array('harold','maude'),
),

 但这样就过于static了,一般用户信息肯定都是存在数据库里,所以这里的规则必须得跟数据库挂钩才行,如何实现呢?我们可以在后面加上一句表达式,比如:

array('allow',
    'actions'=>array('publish'),
    'users'=>array('@'),
    'expression'=>'isset($user->role) && ($user->role==="editor")'
),

 

只有expression里的表达式为true时规则才能通过,于是这条规则的含义就是将“publish”操作的权限限制在已经登录的并且role为editor的用户中。

  Note:$user->role的值必须在用户登录的时候就被赋予,这个过程在身份验证时实现。

  

  还有一种情况就是某个用户只能修改或删除自己创建的内容。比如一个用户创建了某个事件,该用户的ID便与这个事件记录相关联,EventController中修改和删除的操作只能在当前登录用户的ID与事件的ownerId相同时才能被执行。因为accessRules()中的规则必须在加载某个特定的Model前就要被判定,而这种情况下必须要通过加载Model并获取Model中的数据来判断,所以此规则不能在accessRules()中设定。下面有个方法能解决这个问题:

public function actionDelete()
{
    $event = $this->loadEvents(); // Fetch the specific event Model.
    // Can only delete the events they created:
    if ($event->ownerId == Yii::app()->user->id) {
        $event->delete();
    } else {
        throw new CHttpException(403,'Invalid request. You are not allowed to delete this event.');
    }
}