>백엔드 개발 >PHP 튜토리얼 >Yii에서 전면 및 후면 로그인 처리 방법 구현에 대해

Yii에서 전면 및 후면 로그인 처리 방법 구현에 대해

不言
不言원래의
2018-06-19 11:51:371365검색

이 글은 Yii의 새로운 프론트엔드 및 백엔드 로그인 처리 방법을 주로 소개하고, Yii의 프론트엔드 및 백엔드 로그인에 대한 새로운 아이디어와 관련 구현 기술을 구체적으로 분석하여 도움이 필요한 친구들이 참고할 수 있습니다.

이 문서에서는 Yii의 구현 처리를 예시와 함께 설명합니다. 전면 및 후면 로그인을 위한 새로운 방법입니다. 참고하실 수 있도록 자세한 내용은 다음과 같습니다.

현재 프론트엔드와 백엔드 로그인 문제가 관련된 프로젝트를 진행하고 있기 때문에 백엔드를 모듈로 처리하고 있습니다. 많은 사람들이 index.php와 admin.php 두 개의 항목 파일을 넣은 다음 각각 프런트엔드와 백엔드를 가리키는 것을 보았습니다. 이 방법은 매우 훌륭하지만 프런트엔드와 백엔드를 완전히 분리할 수 있지만 항상 이 방법이 조금 무리라고 생각합니다. 이 방법과 두 응용 프로그램의 차이점은 무엇입니까? 하나의 프레임워크를 사용하여 두 개의 앱을 만드는 것이 더 좋습니다. 그리고 공식 Yii 백그라운드 사용 방법도 Module을 사용하는 것입니다. 그러나 Moudle의 방식은 매우 번거로운 문제가 있습니다. 즉, Cwebuser를 사용하여 로그인할 때 프런트엔드와 백엔드가 동시에 로그인과 로그아웃을 수행한다는 점은 명백히 불합리합니다. 아래에 소개할 방법을 찾는데 오랜 시간이 걸렸습니다. 물론, 대부분은 다른 사람들의 방법을 기반으로 하여 약간의 변경을 가한 것입니다. 나의 초기 접근 방식은 백그라운드에 로그인할 때 isadmin 세션을 설정한 다음 프론트 데스크에 로그인할 때 세션에서 로그아웃하는 것이었습니다. 이는 프론트 데스크 로그인인지 백그라운드 로그인인지만 알 수 있었지만, 프런트엔드와 백엔드 모두 로그인을 할 수 없습니다. 즉, 프런트데스크 로그인은 백그라운드로 로그인 후 로그아웃하고, 프런트데스크에 로그인한 후 로그아웃합니다. 이 문제의 근본 원인은 동일한 Cwebuser 인스턴스를 사용하고 프런트엔드 세션과 백엔드 세션을 동시에 설정할 수 없다는 것입니다. 이 문제를 해결하려면 서로 다른 Cwebuser 인스턴스를 사용하여 프런트엔드와 백엔드에 로그인해야 합니다. 다음은 내 접근 방식입니다. 먼저 protected->config->main.php에서 프런트 엔드 사용자(Cwebuser)의 구성을 살펴보세요.

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

Gii를 사용하여 관리자(예: 백그라운드)를 생성합니다. 모듈 이름) module 을 사용하면 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 배열에 저장되어 있으면 인쇄해서 볼 수 있습니다.)

이렇게 프런트엔드와 백엔드가 분리되어 있었는데, 이때 로그아웃을 하면 프런트엔드와 백엔드가 함께 로그아웃된 것을 확인할 수 있습니다. 그래서 logout() 메소드를 찾았고 $destroySession=true 매개변수가 있음을 발견했습니다. logout()만 수행하면 false 매개변수를 추가하면 현재 로그인 인스턴스만 로그아웃됩니다. 세션이 로그아웃되므로 전면 및 후면 세션 접두사를 설정해야 합니다. false 매개변수를 사용하여 로그아웃 방법을 설정하여 세션을 로그아웃하는 방법을 살펴보겠습니다. 보세요, 로그아웃하기 위해 일치하는 접두어를 사용하고 있습니다.

이제 프론트엔드와 백엔드의 로그인과 로그아웃을 분리할 수 있습니다. 이렇게 하면 애플리케이션에 더 가깝습니다. 그렇죠? 헤헤...

설명하는 걸 깜빡할뻔했어요:

/**
* 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]);
  }
}

이해가 안 되신다면 지금 프론트엔드와 백엔드 CWebUser의 구성을 자세히 살펴보세요.

첨부 1: WebUser.php 코드:

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

첨부 2: AdminWebUser.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);
  }
}
?>

첨부 3: 프런트엔드 UserI dentity.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);
  }
}
?>

첨부 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 $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;
  }
}

위 내용은 모두의 학습에 도움이 되기를 바랍니다. PHP 중국어 웹사이트!

관련 권장 사항:

Yii2에서 다중 테이블 관련 쿼리에 Join 및 Joinwith 사용 정보

Yii2 WeChat 백엔드 개발 사용 분석 정보

위 내용은 Yii에서 전면 및 후면 로그인 처리 방법 구현에 대해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.