在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如何得到当前页和上一页的地址?
Nov 27 PHP
Linux fgetcsv取得的数组元素为空字符串的解决方法
Nov 25 PHP
PHP常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
Sep 12 PHP
PHP实现的比较完善的购物车类
Dec 02 PHP
Codeigniter检测表单post数据的方法
Mar 21 PHP
php文件压缩之PHPZip类用法实例
Jun 18 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
Dec 31 PHP
详解WordPress中调用评论模板和循环输出评论的PHP函数
Jan 05 PHP
PHP实现的最大正向匹配算法示例
Dec 19 PHP
php无限极分类实现方法分析
Jul 04 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
Aug 05 PHP
laravel Model 执行事务的实现
Oct 10 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 EOT定界符的使用详解
2008/09/30 PHP
php session 错误
2009/05/21 PHP
php实现MD5加密16位(不要默认的32位)
2013/08/12 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
php类中的各种拦截器用法分析
2014/11/03 PHP
wordpress之js库集合研究介绍
2007/08/17 Javascript
Javascript常用运算符(Operators)-javascript基础教程
2007/12/14 Javascript
jquery 插件学习(二)
2012/08/06 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
2013/08/14 Javascript
javascript实现左右控制无缝滚动
2014/12/31 Javascript
javascript数组去重方法汇总
2015/04/23 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
2016/01/04 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
最全面的百度地图JavaScript离线版开发
2016/09/10 Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
2016/10/10 Javascript
JavaScript变量基本使用方法实例分析
2019/11/15 Javascript
JavaScript数组类型Array相关的属性与方法详解
2020/09/08 Javascript
分享python数据统计的一些小技巧
2016/07/21 Python
Python+MongoDB自增键值的简单实现
2016/11/04 Python
Python设计模式之备忘录模式原理与用法详解
2019/01/15 Python
python 两个一样的字符串用==结果为false问题的解决
2020/03/12 Python
Python爬虫之爬取淘女郎照片示例详解
2020/07/28 Python
Snapfish英国:在线照片打印和个性化照片礼品
2017/01/13 全球购物
Hotels.com南非:酒店预订
2017/11/02 全球购物
超市营业员求职简历的自我评价
2013/10/17 职场文书
超市后勤自我鉴定
2014/01/17 职场文书
秋季校运动会广播稿
2014/02/23 职场文书
主持词开场白
2014/03/17 职场文书
员工保密承诺书
2014/05/28 职场文书
2014年安全生产目标责任书
2014/07/23 职场文书
小学生志愿者活动方案
2014/08/23 职场文书
2014年党小组工作总结
2014/12/20 职场文书
事业单位岗位说明书
2015/10/08 职场文书
大学生社区义工服务心得体会
2016/01/22 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
3050和2060哪个好 性能差多少 差距有多大 谁更有性价比
2022/06/17 数码科技