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


Posted in PHP onJune 20, 2013

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 相关文章推荐
PHP中Session的概念
Oct 09 PHP
dedecms系统常用术语汇总
Apr 03 PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 PHP
根据中文裁减字符串函数的php代码
Dec 03 PHP
2014最热门的24个php类库汇总
Dec 18 PHP
php类的定义与继承用法实例
Jul 07 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
Mar 18 PHP
thinkphp中U方法按路由规则生成url的方法
Mar 12 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
PHP关于foreach复制知识点总结
Jan 28 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
Feb 18 PHP
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
Jun 20 #PHP
php中0,null,empty,空,false,字符串关系的详细介绍
Jun 20 #PHP
解析PHP中数组元素升序、降序以及重新排序的函数
Jun 20 #PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 #PHP
深入解析PHP内存管理之谁动了我的内存
Jun 20 #PHP
解析php中die(),exit(),return的区别
Jun 20 #PHP
有关PHP性能优化的介绍
Jun 20 #PHP
You might like
PHP间隔一段时间执行代码的方法
2014/12/02 PHP
浅谈PHP定义命令空间的几个注意点(推荐)
2016/10/29 PHP
解决thinkphp5未定义变量会抛出异常,页面错误,请稍后再试的问题
2019/10/16 PHP
javascript中的有名函数和无名函数
2007/10/17 Javascript
JS Excel读取和写入操作(模板操作)实现代码
2010/04/11 Javascript
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
2012/01/21 Javascript
Js 回车换行处理的办法及replace方法应用
2013/01/24 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
JavaScript处理解析JSON数据过程详解
2015/09/11 Javascript
开启BootStrap学习之旅
2016/05/04 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
jQuery使用each方法与for语句遍历数组示例
2016/06/16 Javascript
使用json来定义函数,在里面可以定义多个函数的实现方法
2016/10/28 Javascript
JavaScript实现多栏目切换效果
2016/12/12 Javascript
Vue.js学习示例分享
2017/02/05 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
详解VueJS应用中管理用户权限
2018/02/02 Javascript
node结合swig渲染摸板的方法
2018/04/11 Javascript
详解Vue 如何监听Array的变化
2019/06/06 Javascript
vue3.0 上手体验
2020/09/21 Javascript
python删除指定类型(或非指定)的文件实例详解
2015/07/06 Python
详解flask入门模板引擎
2018/07/18 Python
微信小程序python用户认证的实现
2019/07/29 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
pandas参数设置的实用小技巧
2020/08/23 Python
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
中学门卫岗位职责
2013/12/26 职场文书
服装采购员岗位职责
2014/03/15 职场文书
2014春晚主持词
2014/03/25 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
旷课检讨书范文
2014/10/30 职场文书
经典导游欢迎词
2015/01/26 职场文书
大学生就业意向书
2015/05/11 职场文书