在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获取网页内容方法总结
Dec 04 PHP
PHP全概率运算函数(优化版) Webgame开发必备
Jul 04 PHP
PHP中使用CURL模拟登录并获取数据实例
Jul 01 PHP
php使用类继承解决代码重复的问题
Feb 11 PHP
php实现在服务器端调整图片大小的方法
Jun 16 PHP
PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠
Sep 30 PHP
Yii中创建自己的Widget实例
Jan 05 PHP
浅谈htmlentities 、htmlspecialchars、addslashes的使用方法
Dec 09 PHP
浅谈PHP面向对象之访问者模式+组合模式
May 22 PHP
PHP数组式访问接口ArrayAccess用法分析
Dec 28 PHP
PHP设计模式之抽象工厂模式实例分析
Mar 25 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
Oct 02 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缓存函数的使用说明
2013/05/10 PHP
PHP提交表单失败后如何保留已经填写的信息
2014/06/20 PHP
图解找出PHP配置文件php.ini的路径的方法
2014/08/20 PHP
php单例模式示例分享
2015/02/12 PHP
深入剖析PHP中printf()函数格式化使用
2016/05/23 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
js wmp操作代码小结(音乐连播功能)
2008/11/08 Javascript
javascript测试题练习代码
2012/10/10 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
2013/07/09 Javascript
javascript变量声明实例分析
2015/04/25 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
vue2.0开发实践总结之入门篇
2016/12/06 Javascript
js 输入框 正则表达式(菜鸟必看教程)
2017/02/19 Javascript
jQuery+ThinkPHP+Ajax实现即时消息提醒功能实例代码
2017/03/21 jQuery
Angular 开发学习之Angular CLI的安装使用
2017/12/31 Javascript
nodejs读取并去重excel文件
2018/04/22 NodeJs
详解CommonJS和ES6模块循环加载处理的区别
2018/12/26 Javascript
node.js express框架简介与实现
2019/07/23 Javascript
解决iView Table组件宽度只变大不变小的问题
2020/11/13 Javascript
python抓取京东商城手机列表url实例代码
2013/12/18 Python
Python三元运算实现方法
2015/01/12 Python
Pandas统计重复的列里面的值方法
2019/01/30 Python
keras获得model中某一层的某一个Tensor的输出维度教程
2020/01/24 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
Canvas引入跨域的图片导致toDataURL()报错的问题的解决
2018/09/19 HTML / CSS
嘻哈珠宝品牌:KRKC&CO
2020/10/19 全球购物
技校毕业生个人学习的自我评价
2014/02/21 职场文书
开学典礼决心书
2014/03/11 职场文书
产品发布会策划方案
2014/05/12 职场文书
银行青年文明号事迹材料
2014/05/31 职场文书
保研导师推荐信
2015/03/25 职场文书
2015年乡镇信访工作总结
2015/04/07 职场文书
时尚女魔头观后感
2015/06/04 职场文书
2015年支教教师工作总结
2015/07/22 职场文书
使用CSS设置滚动条样式
2022/01/18 HTML / CSS