在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 相关文章推荐
ZF等常用php框架中存在的问题
Jan 10 PHP
php 获得汉字拼音首字母的函数
Aug 01 PHP
php文章内容分页并生成相应的htm静态页面代码
Jun 07 PHP
不支持fsockopen但支持culr环境下下ucenter与modoer通讯问题
Aug 12 PHP
APACHE的AcceptPathInfo指令使用介绍
Jan 18 PHP
php在linux下检测mysql同步状态的方法
Jan 15 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
Feb 16 PHP
php可变长参数处理函数详解
Feb 22 PHP
在PHP 7下安装Swoole与Yar,Yaf的方法教程
Jun 02 PHP
PHP微信公众号开发之微信红包实现方法分析
Jul 14 PHP
PHP使用文件锁解决高并发问题示例
Mar 29 PHP
laravel框架模型和数据库基础操作实例详解
Jan 25 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 常用字符串函数总结
2008/03/15 PHP
测试php连接mysql是否成功的代码分享
2014/01/24 PHP
php常用文件操作函数汇总
2014/11/22 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
PHP实现的统计数据功能详解
2016/12/06 PHP
JavaScript小技巧 2.5 则
2010/09/12 Javascript
jQuery获取css z-index在各种浏览器中的返回值
2010/09/15 Javascript
javascript实现动态侧边栏代码
2014/02/19 Javascript
JavaScript表单通过正则表达式验证电话号码
2014/03/14 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
Javascript页面跳转常见实现方式汇总
2015/11/28 Javascript
JSON遍历方式实例总结
2015/12/07 Javascript
Bootstrap开关(switch)控件学习笔记分享
2016/05/30 Javascript
Javascript中常用的检测方法小结
2016/10/08 Javascript
vuejs2.0实现一个简单的分页示例
2017/02/22 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
解决Nodejs全局安装模块后找不到命令的问题
2018/05/15 NodeJs
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
举例详解Python中threading模块的几个常用方法
2015/06/18 Python
利用Python开发实现简单的记事本
2016/11/15 Python
python实现抖音视频批量下载
2018/06/20 Python
基于python生成器封装的协程类
2019/03/20 Python
Python文字截图识别OCR工具实例解析
2020/03/05 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
Python批量修改xml的坐标值全部转为整数的实例代码
2020/11/26 Python
Tessabit美国:集世界奢侈品和设计师品牌的意大利精品买手店
2020/06/29 全球购物
酒店个人培训自我鉴定
2013/12/11 职场文书
我爱我家教学反思
2014/05/01 职场文书
三八红旗手先进事迹材料
2014/05/13 职场文书
群众路线教育实践活动学习心得体会
2014/10/30 职场文书
2015年财务试用期工作总结
2014/12/24 职场文书
演讲开场白和结束语
2015/05/29 职场文书
小平您好观后感
2015/06/09 职场文书
go语言中fallthrough的用法说明
2021/05/06 Golang
Windows环境下实现批量执行Sql文件
2021/10/05 SQL Server