在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&amp;MYSQL服务器配置说明
Oct 09 PHP
一个简单的PHP投票程序源码
Mar 11 PHP
php中判断字符串是否全是中文或含有中文的实现代码
Sep 16 PHP
基于simple_html_dom的使用小结
Jul 01 PHP
Yii使用ajax验证显示错误messagebox的解决方法
Dec 03 PHP
Zend Framework缓存Cache用法简单实例
Mar 19 PHP
PHP获取当前文件的父目录方法汇总
Jul 21 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
Aug 08 PHP
php实现的SSO单点登录系统接入功能示例分析
Oct 12 PHP
php PDO实现的事务回滚示例
Mar 23 PHP
PHP大文件分片上传的实现方法
Oct 28 PHP
PHP 7.4 新语法之箭头函数实例详解
May 09 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
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
JQuery的$和其它JS发生冲突的快速解决方法
2014/01/24 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
jQuery通过deferred对象管理ajax异步
2016/05/20 Javascript
JS生成不重复的随机数组的简单实例
2016/07/10 Javascript
PhotoSwipe异步动态加载图片方法
2016/08/25 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
JS实现多物体运动的方法详解
2018/01/23 Javascript
JavaScript实现职责链模式概述
2018/01/25 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
vue.js使用v-if实现显示与隐藏功能示例
2018/07/06 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
[04:31]2016国际邀请赛中国区预选赛妖精采访
2016/06/27 DOTA
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
2013/12/03 Python
Python中的jquery PyQuery库使用小结
2014/05/13 Python
python requests 使用快速入门
2017/08/31 Python
django 常用orm操作详解
2017/09/13 Python
Python输出各行命令详解
2018/02/01 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
利用keras使用神经网络预测销量操作
2020/07/07 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
html5与css3小应用
2013/04/03 HTML / CSS
HTML5中判断用户是否正在浏览页面的方法
2014/05/03 HTML / CSS
耐克巴西官方网站:Nike巴西
2016/08/14 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
交通安全演讲稿
2014/01/07 职场文书
党的群众路线教育实践活动批评与自我批评
2014/02/16 职场文书
经济信息系毕业生自荐信范文
2014/03/15 职场文书
文秘自荐信
2014/06/28 职场文书
2014年教师节寄语
2014/08/11 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
大学生操行评语大全
2014/12/31 职场文书
2016党校学习心得体会
2016/01/07 职场文书
手把手教你导入Go语言第三方库
2021/08/04 Golang