在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 11 PHP
php下尝试使用GraphicsMagick的缩略图功能
Jan 01 PHP
PHP下打开phpMyAdmin出现403错误的问题解决方法
May 23 PHP
destoon安全设置中需要设置可写权限的目录及文件
Jun 21 PHP
php使用cookie显示用户上次访问网站日期的方法
Jan 26 PHP
PHP使用PHPexcel导入导出数据的方法
Nov 14 PHP
PHP版本常用的排序算法汇总
Dec 20 PHP
Yii中表单用法实例详解
Jan 05 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
Sep 17 PHP
Laravel框架实现多数据库连接操作详解
Jul 12 PHP
laravel实现登录时监听事件,添加登录用户的记录方法
Sep 30 PHP
Thinkphp页面跳转设置跳转等待时间的操作
Oct 16 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
图解上海144收音机
2021/03/02 无线电
在MongoDB中模拟Auto Increment的php代码
2011/03/06 PHP
php中设置index.php文件为只读的方法
2013/02/06 PHP
跟我学Laravel之安装Laravel
2014/10/15 PHP
PHP中addslashes与mysql_escape_string的区别分析
2016/04/25 PHP
利用php + Laravel如何实现部署自动化详解
2017/10/11 PHP
ThinkPHP框架实现的MySQL数据库备份功能示例
2018/05/24 PHP
js自动闭合html标签(自动补全html标记)
2012/10/04 Javascript
详解JavaScript中的表单验证
2015/06/16 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
jQuery简单创建节点的方法
2016/09/09 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
2017/01/20 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
JS弹窗 JS弹出DIV并使整个页面背景变暗功能的实现代码
2018/04/21 Javascript
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
Vue 中对图片地址进行拼接的方法
2018/09/03 Javascript
Vue中实现权限控制的方法示例
2019/06/07 Javascript
js简单遍历获取对象中的属性值的方法示例
2019/06/19 Javascript
js实现时分秒倒计时
2019/12/03 Javascript
vue输入框使用模糊搜索功能的实现代码
2020/05/26 Javascript
使用js和canvas实现时钟效果
2020/09/08 Javascript
Python编写万花尺图案实例
2021/01/03 Python
解决PDF 转图片时丢文字的一种可能方式
2021/03/04 Python
Myprotein比利时官方网站:欧洲第一运动营养品牌
2020/10/04 全球购物
物业管理个人自我评价
2013/11/08 职场文书
测试工程师岗位职责
2013/11/28 职场文书
秋季运动会表扬稿
2014/01/16 职场文书
《我的信念》教学反思
2014/02/15 职场文书
2014年三八妇女节活动总结
2014/03/01 职场文书
社区矫正工作方案
2014/06/04 职场文书
低碳环保口号
2014/06/12 职场文书
公司踏青活动方案
2014/08/16 职场文书
2014年村官工作总结
2014/11/24 职场文书
挂职个人工作总结
2015/03/05 职场文书
vue3中的组件间通信
2021/03/31 Vue.js
python 爬取豆瓣网页的示例
2021/04/13 Python