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

在yii中新增一个用户验证的方法详解

程序员文章站 2022-05-14 08:37:22
1.为什么要新增一个用户验证:因为我要将网站后台和前台做在同一个yii的应用中.但是前台也包含有会员的管理中心.而这两个用户验证是完全不同的,所以需要两个不同登陆页面,要将...
1.为什么要新增一个用户验证:
因为我要将网站后台和前台做在同一个yii的应用中.但是前台也包含有会员的管理中心.而这两个用户验证是完全不同的,所以需要两个不同登陆页面,要将用户信息保存在不同的cookie或session中.所以需要在一个应用中增加一个用户验证

2.yii的用户验证:
在自定义用户验证前,我们首先要弄清楚yii的验证和授权方式.
为了验证一个用户,我们需要定义一个有验证逻辑的验证类.在yii中这个类需要实现iuseridentity接口,不同的类就可以实现不同的验证方 法.网站登陆一般需要验证的就是用户名和密码,yii提供了cuseridentity类,这个类一般用于验证用户名和密码的类.继承后我们需要重写其中 的authenticate()方法来实现我们自己的验证方法.具体代码如下:
php代码
复制代码 代码如下:

class useridentity extends cuseridentity 

    private $_id; 
    public function authenticate() 
    { 
        $record=user::model()->findbyattributes(array('username'=>$this->username)); 
        if($record===null) 
            $this->errorcode=self::error_username_invalid; 
        else if($record->password!==md5($this->password)) 
            $this->errorcode=self::error_password_invalid; 
        else
        { 
            $this->_id=$record->id; 
            $this->setstate('title', $record->title); 
            $this->errorcode=self::error_none; 
        } 
        return !$this->errorcode; 
    } 
    public function getid() 
    { 
        return $this->_id; 
    } 
}

在用户登陆时则调用如下代码:
php代码
复制代码 代码如下:

// 使用提供的用户名和密码登录用户 
$identity=new useridentity($username,$password); 
if($identity->authenticate()) 
    yii::app()->user->login($identity); 
else
    echo $identity->errormessage;

用户退出时,则调用如下代码:
php代码
复制代码 代码如下:

// 注销当前用户 
yii::app()->user->logout();
 其中的user是yii的一个components.需要在protected/config/main.php中定义

php代码
复制代码 代码如下:

'user'=>array( 
    // enable cookie-based authentication 
    'allowautologin'=>true, 
        'loginurl' => array('site/login'), 
),

这里我们没有指定user的类名.因为在yii中默认user为cwebuser类的实例.
我 们现在已经实现了用户的登陆验证和退出.但是现在无论是否登陆,用户都能访问所有的action,所以下一步我们要对用户访问进行授权.在yii里是通过 access control filter即访问控制过滤器来实现用户授权的.我们看一下一个简单的带有访问控制的controller:
php代码
复制代码 代码如下:

class admindefaultcontroller extends ccontroller 
{  
    public function filters() 
        { 
            return array('accesscontrol'); 
        } 
        public function accessrules() 
        { 
            return array( 
                array( 
                    'allow', 
                    'users' => array('@'), 
                ), 
                array( 
                    'deny', 
                    'users' => array('*') 
                ), 
            ); 
        } 
}

我们在filters方法中设置具体的filter.我们可以看到在filters方法返回的array里有accesscontrol参数,在ccontroller类中有一个filteraccesscontrol方法:
php代码
复制代码 代码如下:

public function filteraccesscontrol($filterchain) 

    $filter=new caccesscontrolfilter; 
    $filter->setrules($this->accessrules()); 
    $filter->filter($filterchain); 
}

在里面新建了一个caccesscontrolfilter实例,并且在setrules时传入了accessrules()方法返回的参数.
$filter->filter($filterchain)则是继续调用其它filter.
而所有具体的授权规则则是定义在accessrules中:
php代码
复制代码 代码如下:

public function accessrules() 
    { 
        return array( 
            array('deny', 
                'actions'=>array('create', 'edit'), 
                'users'=>array('?'), 
            ), 
            array('allow', 
                'actions'=>array('delete'), 
                'roles'=>array('admin'), 
            ), 
            array('deny', 
                'actions'=>array('delete'), 
                'users'=>array('*'), 
            ), 
        ); 
    }

具体规则参见yii的手册.
3.新增一个验证体系:
首先我们从cwebuser继承一个cadminuser:
php代码
复制代码 代码如下:

class cadminwebuser extends cwebuser 

    public $loginurl = array('admin/admin/login'); 
}

我们需要把他放置到components中
如果是全局应用则通过protected/config/main.php的components小节:
php代码
复制代码 代码如下:

'user'=>array( 
    // enable cookie-based authentication 
        'class' => 'cadminuser', 
    'allowautologin'=>true, 
       'loginurl' => array('site/login'), 
),

如果是在modules中则在模块类的init方法中添加如下代码:
php代码
复制代码 代码如下:

$this->setcomponents(array( 
       'adminuser' => array( 
                'class' => 'cadminwebuser', 
                'allowautologin' => false, 
        ) 
));

最后调用方式
php代码
复制代码 代码如下:

//全局应用 
yii::app()->getcomponent('adminuser'); 
//在模块中 
yii::app()->controller->module->getcomponent('adminuser');

但仅仅这样还不够,我们还需要修改controller的filter,我们需要自定义一个filter,来实现另一个用户的验证和授权
第一步自定义一个filter:
php代码
复制代码 代码如下:

class cadminaccesscontrolfilter extends caccesscontrolfilter 

    protected function prefilter($filterchain) 
    { 
        $app=yii::app(); 
        $request=$app->getrequest(); 
        $user = yii::app()->controller->module->getcomponent('adminuser'); 
        $verb=$request->getrequesttype(); 
        $ip=$request->getuserhostaddress(); 

        foreach($this->getrules() as $rule) 
        { 
            if(($allow=$rule->isuserallowed($user,$filterchain->controller,$filterchain->action,$ip,$verb))>0) // allowed 
                break; 
            else if($allow<0) // denied 
            { 
                $this->accessdenied($user); 
                return false; 
            } 
        } 
        return true; 
    } 
}

再重写ccontroller类的filteraccesscontroller方法
php代码
复制代码 代码如下:

public function filteraccesscontrol($filterchain) 

    $filter = new cadminaccesscontrolfilter(); 
    $filter->setrules($this->accessrules()); 
    $filter->filter($filterchain); 

//在这里我们使用自定义的filter类替换了原来的filter

ok,到这里我们就可以在此controller的accessrules()中指定adminuser的授权了