關於Yii中處理前後台登入的方法實現

不言
發布: 2023-04-01 13:30:02
原創
1332 人瀏覽過

這篇文章主要介紹了Yii中實現處理前後台登入的新方法,具體分析了Yii中前後台登入的新思路與相關實現技巧,需要的朋友可以參考下

本文實例講述了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(
      &#39;admin.models.*&#39;,
      &#39;admin.components.*&#39;,
    ));
    //这里重写父类里的组件
    //如有需要还可以参考API添加相应组件
    Yii::app()->setComponents(array(
        &#39;errorHandler&#39;=>array(
            &#39;class&#39;=>&#39;CErrorHandler&#39;,
            &#39;errorAction&#39;=>&#39;admin/default/error&#39;,
        ),
        &#39;admin&#39;=>array(
            &#39;class&#39;=>&#39;AdminWebUser&#39;,//后台登录类实例
            &#39;stateKeyPrefix&#39;=>&#39;admin&#39;,//后台session前缀
            &#39;loginUrl&#39;=>Yii::app()->createUrl(&#39;admin/default/login&#39;),
        ),
    ), false);
    //下面这两行我一直没搞定啥意思,貌似CWebModule里也没generatorPaths属性和findGenerators()方法
    //$this->generatorPaths[]=&#39;admin.generators&#39;;
    //$this->controllerMap=$this->findGenerators();
  }
  public function beforeControllerAction($controller, $action)
  {
    if(parent::beforeControllerAction($controller, $action))
    {
      $route=$controller->id.&#39;/&#39;.$action->id;
      if(!$this->allowIp(Yii::app()->request->userHostAddress) && $route!==&#39;default/error&#39;)
        throw new CHttpException(403,"You are not allowed to access this page.");
      $publicPages=array(
        &#39;default/login&#39;,
        &#39;default/error&#39;,
      );
      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===&#39;*&#39; || $filter===$ip || (($pos=strpos($filter,&#39;*&#39;))!==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(&#39;__userInfo&#39;)) {
      $user=$this->getState(&#39;__userInfo&#39;,array());
      if (isset($user[$name])) {
        return $user[$name];
      }
    }
    return parent::__get($name);
  }
  public function login($identity, $duration) {
    $this->setState(&#39;__userInfo&#39;, $identity->getUser());
    parent::login($identity, $duration);
  }
}
?>
登入後複製

附件2:AdminWebUser.php程式碼

<?php
class AdminWebUser extends CWebUser
{
  public function __get($name)
  {
    if ($this->hasState(&#39;__adminInfo&#39;)) {
      $user=$this->getState(&#39;__adminInfo&#39;,array());
      if (isset($user[$name])) {
        return $user[$name];
      }
    }
    return parent::__get($name);
  }
  public function login($identity, $duration) {
    $this->setState(&#39;__adminInfo&#39;, $identity->getUser());
    parent::login($identity, $duration);
  }
}
?>
登入後複製

附件3:前台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 &#39;demo&#39;.
   * 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(&#39;username=:username&#39;,array(&#39;:username&#39;=>$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;
  }
}
登入後複製

##附件4:後台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 &#39;demo&#39;.
   * 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(&#39;username=:username&#39;,array(&#39;:username&#39;=>$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中文網!

相關推薦:

關於Yii2中使用join和joinwith進行多表關聯查詢

#########關於利用Yii2微信後台開發的解析########################

以上是關於Yii中處理前後台登入的方法實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
yii
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板