在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 相关文章推荐
用文本作数据处理
Oct 09 PHP
php mysql数据库操作类
Jun 04 PHP
PHP 采集获取指定网址的内容
Jan 05 PHP
第七章 php自定义函数实现代码
Dec 30 PHP
利用php递归实现无限分类 格式化数组的详解
Jun 08 PHP
浅析PHP微信支付通知的处理方式
May 25 PHP
ThinkPHP之M方法实例详解
Jun 20 PHP
php中strstr、strrchr、substr、stristr四个函数的区别总结
Sep 22 PHP
php魔术函数__call()用法实例分析
Feb 13 PHP
php写一个函数,实现扫描并打印出自定目录下(含子目录)所有jpg文件名
May 26 PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
Jun 19 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
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
2010/05/04 PHP
用 Composer构建自己的 PHP 框架之构建路由
2014/10/30 PHP
php+lottery.js实现九宫格抽奖功能
2019/07/21 PHP
JQuery 常用操作代码
2010/03/14 Javascript
修改jQuery Validation里默认的验证方法
2012/02/14 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
2013/11/25 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
javascript实现的一个随机点名功能
2014/08/26 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
2016/06/02 Javascript
检查表单元素的值是否为空的实例代码
2016/06/16 Javascript
Javascript点击其他任意地方隐藏关闭DIV实例
2016/06/21 Javascript
webpack+vue.js实现组件化详解
2016/10/12 Javascript
jQuery设置图片等比例缩小的方法
2017/04/29 jQuery
关于webpack2和模块打包的新手指南(小结)
2017/08/07 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
js使用html2canvas实现屏幕截取的示例代码
2017/08/28 Javascript
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
解决layui调用自定义方法提示未定义的问题
2019/09/14 Javascript
在Python中进行自动化单元测试的教程
2015/04/15 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
Python map及filter函数使用方法解析
2020/08/06 Python
用CSS3实现背景渐变的方法
2015/07/14 HTML / CSS
一份全面的PHP面试问题考卷
2012/07/15 面试题
C语言面试题
2015/10/30 面试题
马云北大演讲完整版:真心话,什么才是阿里的核心竞争力?
2014/04/04 职场文书
给校长的建议书500字
2014/05/15 职场文书
优秀党员自我评价范文
2014/09/15 职场文书
2014大四本科生自我鉴定总结
2014/10/04 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
优秀党员事迹材料
2014/12/18 职场文书
运动会开幕式通讯稿
2015/07/18 职场文书
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js
Python如何用re模块实现简易tokenizer
2022/05/02 Python
mysql幻读详解实例以及解决办法
2022/06/16 MySQL