《PHP應用:Yii中實現處理前后臺登錄的新方法》要點:
本文介紹了PHP應用:Yii中實現處理前后臺登錄的新方法,希望對您有用。如果有疑問,可以聯系我們。
相關主題:YII框架
PHP實戰本文實例講述了Yii中實現處理前后臺登錄的新辦法.分享給大家供大家參考,具體如下:
PHP實戰因為最近在做一個項目涉及到前后臺登錄問題,我是把后臺作為一個模塊(Module)來處理的.我看很多人放兩個入口文件index.php和admin.php,然后分別指向前臺和后臺.這種辦法固然很好,可以將前后臺完全分離,但我總覺得這種方式有點牽強,這和兩個應用啥區別?還不如做兩個App用一個framework更好.而且Yii官方后臺使用辦法也是使用Module的方式.但是Moudle的方式有一個很頭疼的問題,就是在使用Cwebuser登錄時會出現前后臺一起登錄一起退出的問題,這顯然是不合理的.我糾結了很久才找到下文即將介紹的辦法,當然,很多也是參考別人的,自己稍作了改動.我一開始的做法是在后臺登錄時設置一個isadmin的session,然后再前臺登錄時注銷這個session,這樣做只能辨別是前臺登錄還是后臺登錄,但做不到前后臺一起登錄,也即前臺登錄了后臺就退出了,后臺登錄了前臺就退出了.出現這種原因的根本原因是我們使用了同一個Cwebuser實例,不能同時設置前后臺session,要解決這個問題就要將前后臺使用不同的Cwebuser實例登錄.下面是我的做法,首先看protected->config->main.php里對前臺user(Cwebuser)的配置:
PHP實戰
'user'=>array(
'class'=>'WebUser',//這個WebUser是繼承CwebUser,稍后給出它的代碼
'stateKeyPrefix'=>'member',//這個是設置前臺session的前綴
'allowAutoLogin'=>true,//這里設置允許cookie保存登錄信息,一邊下次自動登錄
),
PHP實戰在你用Gii生成一個admin(即后臺模塊名稱)模塊時,會在module->admin下生成一個AdminModule.php文件,該類繼承了CWebModule類,下面給出這個文件的代碼,關鍵之處就在該文件,望大家仔細研究:
PHP實戰
<?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;
}
}
?>
PHP實戰AdminModule 的init()辦法就是給后臺配置另外的登錄實例,讓前后臺使用不同的CWebUser,并設置后臺session前綴,以便與前臺session區別開來(他們同事存在$_SESSION這個數組里,你可以打印出來看看).
PHP實戰這樣就已經做到了前后臺登錄分離開了,但是此時你退出的話你就會發現前后臺一起退出了.于是我找到了logout()這個辦法,發現他有一個參數$destroySession=true,原來如此,如果你只是logout()的話那就會將session全部注銷,加一個false參數的話就只會注銷當前登錄實例的session了,這也就是為什么要設置前后臺session前綴的原因了,下面我們看看設置了false參數的logout辦法是如何注銷session的:
PHP實戰
/**
* 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]);
}
}
PHP實戰看到沒,就是利用匹配前綴的去注銷的.
PHP實戰到此,我們就可以做到前后臺登錄分離,退出分離了.這樣才更像一個應用,是吧?嘿嘿…
PHP實戰差點忘了說明一下:
PHP實戰
Yii::app()->user //前臺拜訪用戶信息方法
Yii::app()->admin //后臺拜訪用戶信息方法
PHP實戰不懂的仔細看一下剛才前后臺CWebUser的配置.
PHP實戰附件1:WebUser.php代碼:
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);
}
}
?>
PHP實戰附件2:AdminWebUser.php代碼
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);
}
}
?>
PHP實戰附件3:前臺UserIdentity.php代碼
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;
}
}
PHP實戰附件4:后臺UserIdentity.php代碼
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;
}
}
PHP實戰希望本文所述對大家基于Yii框架的PHP程序設計有所贊助.
維易PHP培訓學院每天發布《PHP應用:Yii中實現處理前后臺登錄的新方法》等實戰技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養人才。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/7976.html