Maison  >  Article  >  développement back-end  >  À propos de l'implémentation de la méthode de gestion des connexions front et back dans Yii

À propos de l'implémentation de la méthode de gestion des connexions front et back dans Yii

不言
不言original
2018-06-19 11:51:371310parcourir

Cet article présente principalement la nouvelle méthode de gestion de la connexion front-end et back-end dans Yii, et analyse spécifiquement les nouvelles idées et techniques de mise en œuvre associées de la connexion front-end et back-end dans Yii. Les amis dans le besoin peuvent se référer. à l'exemple de cet article

Décrit la nouvelle méthode de gestion des connexions avant et arrière dans Yii. J'aimerais le partager avec vous pour votre référence. Les détails sont les suivants :

Parce que je travaille actuellement sur un projet qui implique des problèmes de connexion au front et au backend, je gère le backend comme un module. Je vois que beaucoup de gens mettent deux fichiers d'entrée index.php et admin.php, puis pointent respectivement vers le frontend et le backend. Bien que cette méthode soit très bonne, elle peut complètement séparer le front et le backend, mais j'ai toujours l'impression que cette méthode est un peu tirée par les cheveux. Quelle est la différence entre celle-ci et les deux applications ? Il est préférable de créer deux applications en utilisant un seul framework. Et la méthode officielle d'utilisation en arrière-plan de Yii consiste également à utiliser Module. Mais la méthode de Moudle a un problème très gênant, c'est-à-dire que lors de l'utilisation de Cwebuser pour se connecter, il y aura un problème de connexion et de déconnexion en même temps au front et au backend, ce qui est évidemment déraisonnable. Il m'a fallu beaucoup de temps pour trouver la méthode qui sera présentée ci-dessous. Bien sûr, beaucoup d'entre elles étaient basées sur les méthodes d'autres personnes et j'ai apporté de légères modifications. Mon approche initiale consistait à configurer une session isadmin lors de la connexion au backend, puis à me déconnecter de la session lors de la connexion au frontend. Cela ne pouvait que dire s'il s'agissait d'une connexion frontend ou d'une connexion en arrière-plan, mais cela ne pouvait pas. Ne vous connectez pas à la fois au frontend et au backend, c'est-à-dire connectez-vous au frontend après vous être connecté en arrière-plan et déconnectez-vous après vous être connecté à la réception. La cause première de ce problème est que nous utilisons la même instance Cwebuser et que nous ne pouvons pas configurer de sessions front-end et back-end en même temps. Pour résoudre ce problème, nous devons utiliser différentes instances Cwebuser pour nous connecter au front-end et au back-end. Voici mon approche. Tout d’abord, regardez la configuration de l’utilisateur frontal (Cwebuser) dans protected->config->main.php :

'user'=>array(
  'class'=>'WebUser',//这个WebUser是继承CwebUser,稍后给出它的代码
  'stateKeyPrefix'=>'member',//这个是设置前台session的前缀
  'allowAutoLogin'=>true,//这里设置允许cookie保存登录信息,一边下次自动登录
),

Lorsque vous utilisez Gii pour générer un module admin (nom du module backend), un fichier AdminModule.php sera généré sous module->admin. Cette classe hérite de la classe CWebModule. Le point clé est que dans ce document, j'espère que vous l'étudierez attentivement :

<?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;
  }
}
?>

La méthode init() d'AdminModule consiste à configurer une autre instance de connexion pour le backend, afin que le front et le backend puissent utiliser différents CWebUser, et définir le préfixe de session en arrière-plan pour le distinguer de la session front (ils sont stockés dans le tableau $_SESSION, vous pouvez l'imprimer pour voir).

De cette façon, les connexions avant et arrière ont été séparées, mais si vous vous déconnectez à ce moment-là, vous constaterez que les connexions avant et arrière se sont déconnectées ensemble. J'ai donc trouvé la méthode logout() et j'ai découvert qu'elle avait un paramètre $destroySession=true. Il s'avère que si vous vous déconnectez simplement(), toutes les sessions seront déconnectées. Si vous ajoutez un paramètre false, seule l'instance de connexion actuelle. sera déconnecté. session, c'est pourquoi il est nécessaire de définir les préfixes de session avant et arrière. Voyons comment la méthode de déconnexion avec le paramètre false est définie pour déconnecter la 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]);
  }
}

Avez-vous vu que vous utilisez le préfixe correspondant pour vous déconnecter ?

À ce stade, nous pouvons séparer la connexion et la déconnexion du front et du backend. Cela ressemble davantage à une application, n'est-ce pas ? Héhé...

J'ai failli oublier d'expliquer :

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

Si tu ne comprends pas, regarde de plus près le configuration du CWebUser avant et arrière à l'instant.

Pièce jointe 1 : Code 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);
  }
}
?>

Pièce jointe 2 : AdminWebUser.php Code

<?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);
  }
}
?>

Pièce jointe 3 : Code Front-end 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;
  }
}

Pièce jointe 4 : Code Backend 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;
  }
}

Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

À propos de l'utilisation de join et joinwith pour les requêtes liées à plusieurs tables dans Yii2

À propos de l'utilisation de Yii2 WeChat backend Analyse développée

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn