2016-07-10 8 views
1

他のデバイスからのログインを防止しようとしています。そして、すべての研究の後、私はセッションを使って見つけました。私はyii2フレームワークのデフォルトのログインシステムを使用しています。これらのコードをuserモデルに追加しました。 ユーザモデルは次のとおりです。yii2フレームワークの複数のデバイスからのログインを防止する

<?php 
namespace app\models; 
use Yii; 

//app\models\Users is the model generated using Gii from users table 

use app\models\Users as DbUser; 

class User extends \yii\base\Object implements \yii\web\IdentityInterface { 

public $id; 
public $username; 
public $password; 
public $authKey; 
public $token; 
public $email; 
public $any; 
public $user_type; 

/** 
* @inheritdoc 
*/ 
public static function findIdentity($id) { 
    $dbUser = DbUser::find() 
      ->where([ 
       "id" => $id 
      ]) 
      ->one(); 
    if (!count($dbUser)) { 
     return null; 
    } 
    return new static($dbUser); 
} 

/** 
* @inheritdoc 
*/ 
public static function findIdentityByAccessToken($token, $userType = null) { 

    $dbUser = DbUser::find() 
      ->where(["token" => $token]) 
      ->one(); 
    if (!count($dbUser)) { 
     return null; 
    } 
    return new static($dbUser); 
} 

/** 
* Finds user by username 
* 
* @param string  $username 
* @return static|null 
*/ 
public static function findByUsername($username) { 
    $dbUser = DbUser::find() 
      ->where([ 
       "username" => $username 
      ]) 
      ->one(); 
    if (!count($dbUser)) 
    { 
        return null; 
    } 
    return new static($dbUser); 
} 

/** 
* @inheritdoc 
*/ 
public function getId() { 
    return $this->id; 
} 

/** 
* @inheritdoc 
*/ 
public function getAuthKey() 
{ 
    return $this->authKey; 
} 

/** 
* @inheritdoc 
*/ 
public function validateAuthKey($authKey) 
{ 
    return $this->authKey === $authKey; 
} 

/** 
* Validates password 
* 
* @param string $password password to validate 
* @return boolean if password provided is valid for current user 
*/ 
public function validatePassword($password) 
    { 

     return Yii::$app->getSecurity()->validatePassword($password, $this->password); 
    } 



public function session_validate() 
    { 

     // Encrypt information about this session 
     $user_agent = $this->session_hash_string($_SERVER['HTTP_USER_AGENT'], $this->any); 

     // Check for instance of session 
     if (session_exists() == false) 
     { 
      // The session does not exist, create it 
      $this->session_reset($user_agent); 
     } 

     // Match the hashed key in session against the new hashed string 
     if ($this->session_match($user_agent)) 
     { 
      return true; 
     } 

     // The hashed string is different, reset session 
     $this->session_reset($user_agent); 
     return false; 
    } 

    /** 
    * session_exists() 
    * Will check if the needed session keys exists. 
    * 
    * @return {boolean} True if keys exists, else false 
    */ 

    private function session_exists() 
    { 
     return isset($_SESSION['USER_AGENT_KEY']) && isset($_SESSION['INIT']); 
    } 

    /** 
    * session_match() 
    * Compares the session secret with the current generated secret. 
    * 
    * @param {String} $user_agent The encrypted key 
    */ 

    private function session_match($user_agent) 
    { 
     // Validate the agent and initiated 
     return $_SESSION['USER_AGENT_KEY'] == $user_agent && $_SESSION['INIT'] == true; 
    } 

    /** 
    * session_encrypt() 
    * Generates a unique encrypted string 
    * 
    * @param {String} $user_agent  The http_user_agent constant 
    * @param {String} $unique_string Something unique for the user (email, etc) 
    */ 

    private function session_hash_string($user_agent, $unique_string) 
    { 
     return md5($user_agent.$unique_string); 
    } 

    /** 
    * session_reset() 
    * Will regenerate the session_id (the local file) and build a new 
    * secret for the user. 
    * 
    * @param {String} $user_agent 
    */ 

    private function session_reset($user_agent) 
    { 
     // Create new id 
     session_regenerate_id(TRUE); 
     $_SESSION = array(); 
     $_SESSION['INIT'] = true; 

     // Set hashed http user agent 
     $_SESSION['USER_AGENT_KEY'] = $user_agent; 
    } 

    /** 
    * Destroys the session 
    */ 

    private function session_destroy() 
    { 
     // Destroy session 
     session_destroy(); 
    } 

} 

答えて

0

あなたは、ユーザーのアイデンティティに格納し、同様にDBに保存されますログインプロセス中に追加の認証コードを生成することができます。ユーザーがアクションを呼び出すたびに、彼のコードはdbに保存されたこのコードと比較され、一致しない場合、ユーザーは強制的にログアウトされます。この方法で最新のログインだけが有効です。これを参照してくださいlink

+0

私は強制的にログアウトするためにまだログインしていない別のものからのログインを防止しようとしています。 – micky

+0

でも同じことが言えます。初めてログインするときにセッションキーをDBでアクティブに設定します。ログインプロシージャが呼び出されるたびに、セッションキーのステータスを確認します。セッションキーがアクティブな場合、第2のデバイスからのログインを拒否します。 –

+0

これは、ログアウトしてブラウザを手動で閉じると問題が発生します。 – micky

関連する問題