`

Yii中处理前后台登录新方法

 
阅读更多
因为最近在做一个项目涉及到前后台登录问题,我是把后台作为一个模块(Module)来处理的。我看很多人放两个入口文件index.php和admin.php,然后分别指向前台和后台。这种方法固然很好,可以将前后台完全分离,但我总觉得这种方式有点牵强,这和两个应用啥区别?还不如做两个App用一个framework更好。而且Yii官方后台使用方法也是使用Module的方式。但是Moudle的方式有一个很头疼的问题,就是在使用Cwebuser登录时会出现前后台一起登录一起退出的问题,这显然是不合理的。我纠结了很久才找到下文即将介绍的方法,当然,很多也是参考别人的,自己稍作了改动。我一开始的做法是在后台登录时设置一个isadmin的session,然后再前台登录时注销这个session,这样做只能辨别是前台登录还是后台登录,但做不到前后台一起登录,也即前台登录了后台就退出了,后台登录了前台就退出了。出现这种原因的根本原因是我们使用了同一个Cwebuser实例,不能同时设置前后台session,要解决这个问题就要将前后台使用不同的Cwebuser实例登录。下面是我的做法,首先看protected->config->main.php里对前台user(Cwebuser)的配置:

'user'=>array(
'class'=>'WebUser',//这个WebUser是继承CwebUser,稍后给出它的代码
'stateKeyPrefix'=>'member',//这个是设置前台session的前缀
'allowAutoLogin'=>true,//这里设置允许cookie保存登录信息,一边下次自动登录
),
在你用Gii生成一个admin(即后台模块名称)模块时,会在module->admin下生成一个AdminModule.php文件,该类继承了CWebModule类,下面给出这个文件的代码,关键之处就在该文件,望大家仔细研究:
<?php
class AdminModule extends CWebModule
{
public function init()
{
// this method is called when the module is being created
// you may place code here to customize the module or the application
parent::init();//这步是调用main.php里的配置文件
// import the module-level models and componen
$this->setImport(array(
'admin.models.*',
'admin.components.*',
));
//这里重写父类里的组件
//如有需要还可以参考API添加相应组件
   Yii::app()->setComponents(array(
   'errorHandler'=>array(
   'class'=>'CErrorHandler',
   'errorAction'=>'admin/default/error',
   ),
   'admin'=>array(
   'class'=>'AdminWebUser',//后台登录类实例
   'stateKeyPrefix'=>'admin',//后台session前缀
   'loginUrl'=>Yii::app()->createUrl('admin/default/login'),
   ),
   ), false);
   //下面这两行我一直没搞定啥意思,貌似CWebModule里也没generatorPaths属性和findGenerators()方法
   //$this->generatorPaths[]='admin.generators';
   //$this->controllerMap=$this->findGenerators();
}

public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
$route=$controller->id.'/'.$action->id;
if(!$this->allowIp(Yii::app()->request->userHostAddress) && $route!=='default/error')
throw new CHttpException(403,"You are not allowed to access this page.");
$publicPages=array(
'default/login',
'default/error',
);

if(Yii::app()->admin->isGuest && !in_array($route,$publicPages))
Yii::app()->admin->loginRequired();
else
return true;
}
return false;
}

protected function allowIp($ip)
{
if(empty($this->ipFilters))
return true;
foreach($this->ipFilters as $filter)
{
if($filter==='*' || $filter===$ip || (($pos=strpos($filter,'*'))!==false && !strncmp($ip,$filter,$pos)))
return true;
}
return false;
}
}
?>
AdminModule 的init()方法就是给后台配置另外的登录实例,让前后台使用不同的CWebUser,并设置后台session前缀,以便与前台session区别开来(他们同事存在$_SESSION这个数组里,你可以打印出来看看)。
这样就已经做到了前后台登录分离开了,但是此时你退出的话你就会发现前后台一起退出了。于是我找到了logout()这个方法,发现他有一个参数$destroySession=true,原来如此,如果你只是logout()的话那就会将session全部注销,加一个false参数的话就只会注销当前登录实例的session了,这也就是为什么要设置前后台session前缀的原因了,下面我们看看设置了false参数的logout方法是如何注销session的:
/**
* Clears all user identity information from persistent storage.
* This will remove the data stored via {@link setState}.
*/
public function clearStates()
{
$keys=array_keys($_SESSION);
$prefix=$this->getStateKeyPrefix();
$n=strlen($prefix);
foreach($keys as $key)
{
if(!strncmp($key,$prefix,$n))
unset($_SESSION[$key]);
}
}
看到没,就是利用匹配前缀的去注销的。
到此,我们就可以做到前后台登录分离,退出分离了。这样才更像一个应用,是吧?嘿嘿…
差点忘了说明一下:
Yii::app()->user //前台访问用户信息方法

Yii::app()->admin //后台访问用户信息方法

不懂的仔细看一下刚才前后台CWebUser的配置。

附件1:WebUser.php代码:

<?php
class WebUser extends CWebUser
{
public function __get($name)
{
if ($this->hasState('__userInfo')) {
$user=$this->getState('__userInfo',array());
if (isset($user[$name])) {
return $user[$name];
}
}

return parent::__get($name);
}

public function login($identity, $duration) {
$this->setState('__userInfo', $identity->getUser());
parent::login($identity, $duration);
}
}
?>
附件2:AdminWebUser.php代码
<?php
class AdminWebUser extends CWebUser
{
public function __get($name)
{
if ($this->hasState('__adminInfo')) {
$user=$this->getState('__adminInfo',array());
if (isset($user[$name])) {
return $user[$name];
}
}

return parent::__get($name);
}

public function login($identity, $duration) {
$this->setState('__adminInfo', $identity->getUser());
parent::login($identity, $duration);
}
}
?>
附件三:前台UserIdentity.php代码
<?php

/**
* UserIdentity represents the data needed to identity a user.
* It contains the authentication method that checks if the provided
* data can identity the user.
*/
class UserIdentity extends CUserIdentity
{
/**
* Authenticates a user.
* The example implementation makes sure if the username and password
* are both 'demo'.
* In practical applications, this should be changed to authenticate
* against some persistent user identity storage (e.g. database).
* @return boolean whether authentication succeeds.
*/
public $user;
public $_id;
public $username;
public function authenticate()
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;
$user=User::model()->find('username=:username',array(':username'=>$this->username));
if ($user)
{
$encrypted_passwd=trim($user->password);
$inputpassword = trim(md5($this->password));
if($inputpassword===$encrypted_passwd)
{
$this->errorCode=self::ERROR_NONE;
$this->setUser($user);
$this->_id=$user->id;
$this->username=$user->username;
//if(isset(Yii::app()->user->thisisadmin))
   // unset (Yii::app()->user->thisisadmin);
}
else
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;

}
}
else
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}

unset($user);
return !$this->errorCode;

}
public function getUser()
{
return $this->user;
}

public function getId()
{
return $this->_id;
}

public function getUserName()
{
return $this->username;
}

public function setUser(CActiveRecord $user)
{
$this->user=$user->attributes;
}
}
附件四:后台UserIdentity.php代码
<?php

/**
* UserIdentity represents the data needed to identity a user.
* It contains the authentication method that checks if the provided
* data can identity the user.
*/
class UserIdentity extends CUserIdentity
{
/**
* Authenticates a user.
* The example implementation makes sure if the username and password
* are both 'demo'.
* In practical applications, this should be changed to authenticate
* against some persistent user identity storage (e.g. database).
* @return boolean whether authentication succeeds.
*/
public $admin;
public $_id;
public $username;
public function authenticate()
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;
$user=Staff::model()->find('username=:username',array(':username'=>$this->username));
if ($user)
{
$encrypted_passwd=trim($user->password);
$inputpassword = trim(md5($this->password));
if($inputpassword===$encrypted_passwd)
{
$this->errorCode=self::ERROR_NONE;
$this->setUser($user);
$this->_id=$user->id;
$this->username=$user->username;
   // Yii::app()->user->setState("thisisadmin", "true");
}
else
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;

}
}
else
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}

unset($user);
return !$this->errorCode;

}
public function getUser()
{
return $this->admin;
}

public function getId()
{
return $this->_id;
}

public function getUserName()
{
return $this->username;
}

public function setUser(CActiveRecord $user)
{
$this->admin=$user->attributes;
}
}
分享到:
评论

相关推荐

    Yii中实现处理前后台登录的新方法

    主要介绍了Yii中实现处理前后台登录的新方法,具体分析了Yii中前后台登录的新思路与相关实现技巧,需要的朋友可以参考下

    yii简易后台基础模板

    yii简易后台基础模板

    yii2 通用后台系统

    yii 2.0通用后台系统管理,实现注册登录上传用户自定义头像

    yii2.0后台源码

    带权限管理的yii2.0后台框架,适合任何情况,最新的值得使用

    Yii 前后台分离 demo

    NULL 博文链接:https://hudeyong926.iteye.com/blog/1396657

    yii框架中文文档、yii中文手册教程

    yii1.1中文文档 yii框架中文手册教程.pdf

    Yii 的登录流程

    Yii是一个全栈式的MVC框架,所谓全栈式指的是Yii框架本身实现了web开发中所要用到的所有功能,比如MVC,ORM(DAO/ActiveRecord), 全球化(I18N/L10N), 缓存(caching), 基于jQuery Ajax支持(jQuery-based AJAX support), ...

    Yii2参考手册-新

    Yii2参考手册,Yii2中文手册完整版

    Yii2中文手册(中文教程完整版)

    Yii 2.0 权威指南 本教程的发布遵循 Yii 文档使用许可. 版权所有 2014 (c) Yii Software LLC. 介绍 已定稿 关于 Yii 已定稿 从 Yii 1.1 升级 入门 已定稿 安装 Yii 已定稿 运行应用 已定稿 第一次问候 已定稿 ...

    YII后台源码

    yii2后台,可用于网站后台界面的建设,简介,明了的界面!!!

    Yii2-Admin 后台模板源代码文件

    系统基于yii2高级版本开发,后台模板使用的 Ace Admin。对于一般的后台开发,比较方便; 对于数据表的CURL操作都有封装,且所有操作都有权限控制。现在这个项目只是一个示例项目, 主要功能被我移到: [jinxing/yii2-...

    Yii 中文帮助文档

    它将 Web 编程中的可重用性发挥到极致,能够显著加速开发进程。Yii(读作“易”)代表简单(easy)、高效(efficient)、可扩展(extensible)。 需求 要运行一个基于 Yii 开发的 Web 应用,你需要一个支持 PHP 5.1.0 ...

    YII框架中文手册

    YII框架中文手册,希望帮助需要帮助的人!

    yii 最新版

    yii 最新版

    Yii2.0中文学习手册

    Yii2.0中文学习手册

    Yii2 中实现单点登录的方法

    主要介绍了Yii2 中实现单点登录的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    yii框架yii框架yii框架yii框架yii框架

    很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架很好用yii框架

    Yii中文教程

    权威的yii框架中文版开发文档,希望能够为您的yii框架学习带来帮助,让你的技术更上一层楼! zhihuizhan.com

    yii框架中文手册教程和YII模板

    yii框架中文手册教程和YII模板 我很辛苦才找到的

Global site tag (gtag.js) - Google Analytics