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

所属分类: 网络编程 / PHP编程 阅读数: 1875
收藏 0 赞 0 分享
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的授权了
更多精彩内容其他人还在看

php导出CSV抽象类实例

这篇文章主要介绍了php导出CSV抽象类及其用法示例,可实现循环导出功能,从而避免内存不足的问题,需要的朋友可以参考下
收藏 0 赞 0 分享

php实现的zip文件内容比较类

这篇文章主要介绍了php实现的zip文件内容比较类及其用法,可实现比较两个zip文件的内容,返回新增、删除、及相同的文件列表,是非常实用的技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

php实现获取及设置用户访问页面语言类

这篇文章主要介绍了php实现获取及设置用户访问页面语言类,可实现获取/设置用户访问的页面语言,如果用户没有设置访问语言,则读取Accept-Language,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件

最近做一个在线教学网的项目,需要实现上传任意格式视频自动为h264标准视频,使用html5播放。最终使用PHP+FFMPEG实现,在此将详细解决方案分享给大家!
收藏 0 赞 0 分享

PHP会话控制:Session与Cookie详解

这篇文章主要介绍了PHP会话控制:Session与Cookie详解,本文详细讲解了PHP中Session与Cookie的相关知识,涵盖面较广,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享

这篇文章主要介绍了PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享,这是一个比较常用的功能,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP获取mysql数据表的字段名称和详细信息的方法

这篇文章主要介绍了PHP获取mysql数据表的字段名称和详细信息的方法,本文同时还给出了获取数据表结构、列出数据库数据表等方法,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP中的output_buffering详细介绍

这篇文章主要介绍了PHP中的output_buffering详细介绍,本文讲解了output buffering的一些高级用法,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP错误Warning: Cannot modify header information - headers already sent by解决方法

这篇文章主要介绍了PHP错误Warning: Cannot modify header information - headers already sent by解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP常用编译参数中文说明

这篇文章主要介绍了PHP常用编译参数中文说明,本文用详细的中文注解了PHP编译参数的作用,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多