在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 header Content-Type类型小结
Jul 03 PHP
给初学者的30条PHP最佳实践(荒野无灯)
Aug 02 PHP
PHP源码之explode使用说明
Aug 05 PHP
php简单开启gzip压缩方法(zlib.output_compression)
Apr 13 PHP
解析PHP获取当前网址及域名的实现代码
Jun 23 PHP
php字符串截取的简单方法
Jul 04 PHP
解析WordPress中函数钩子hook的作用及基本用法
Dec 22 PHP
Yii2搭建后台并实现rbac权限控制完整实例教程
Apr 28 PHP
PHP邮箱验证示例教程
Jun 01 PHP
PHP简单实现数字分页功能示例
Aug 24 PHP
Laravel 5.3 学习笔记之 安装
Aug 28 PHP
php提交表单时保留多个空格及换行的文本样式的方法
Jun 20 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与javascript对多项选择的处理
2006/10/09 PHP
PHP开发文件系统实例讲解
2006/10/09 PHP
MayFish PHP的MVC架构的开发框架
2009/08/13 PHP
php数组对百万数据进行排除重复数据的实现代码
2010/06/08 PHP
php自动获取字符串编码函数mb_detect_encoding
2011/05/31 PHP
PHP中使用mktime获取时间戳的一个黑色幽默分析
2012/05/31 PHP
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
WordPress中邮件的一些修改和自定义技巧
2015/12/15 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
2019/12/18 PHP
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
2014/12/12 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
详解JavaScript逻辑Not运算符
2015/12/04 Javascript
解析利用javascript如何判断一个数为素数
2016/12/08 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
jQuery实现文章图片弹出放大效果
2017/04/06 jQuery
前端构建工具之gulp的语法教程
2017/06/12 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
koa-router源码学习小结
2018/09/07 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
[01:28]一分钟告诉你DOTA2 TI9不朽宝藏Ⅱ中有什么!
2019/07/09 DOTA
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python3.4编程实现简单抓取爬虫功能示例
2017/09/14 Python
神经网络理论基础及Python实现详解
2017/12/15 Python
Python断言assert的用法代码解析
2018/02/03 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
光棍节联谊晚会活动策划书
2014/10/10 职场文书
签证工作证明模板
2015/06/15 职场文书
2015年秋季运动会前导词
2015/07/20 职场文书
子女赡养老人协议书
2016/03/23 职场文书
2019个人工作总结
2019/06/21 职场文书