2013-04-12 47 views
0

這裏是我的控制器:笨重定向後控制器鉤環

<?php 
    class Check_Login { 
    var $CI; 
    var $class; 
    var $allowed_klasses = array('user', 'testing', 'home', 'lesson_assets', 's3_handler', 'ajax', 'api', 'pages', 'invite', 'mail', 'partner', 'renew', 'store', 'news', 'breathe','popup','subscription', 'lessons'); 

    public function __construct() { 
     $this->CI =& get_instance(); 

     if(!isset($this->CI->session)) { 
     $this->CI->load->library('session'); 
     } 

     if(!nash_logged_in()) { 
     $this->CI->session->sess_destroy(); 
     redirect('/'); 
     } 

     $this->_set_accessed_klass(); 
    } 

    public function auth_check() { 
     if($this->CI->session->userdata('id')) { 
     $query = $CI->db->query("SELECT authentication_token FROM users WHERE id = ".$this->CI->session->userdata('id')." AND authentication_token IS NOT NULL"); 
     if(!in_array($this->class, $this->allowed_klasses)) { 
      if($query->num_rows() == 0){ 
      redirect('/user/logout'); 
      } 
     }else{ 
      return; 
     } 
     }else{ 
     return; 
     } 
    } 

    private function _set_accessed_klass() { 
     $this->class = $this->CI->router->fetch_class(); 
    } 
    } 

我指太行是:

if(!nash_logged_in()) { 
     $this->CI->session->sess_destroy(); 
     redirect('/'); 
     } 

本質上,應用程序使用nash_logged_in()方法檢查對我們的OAuth系統查看用戶是否真正「登錄」。發生這種情況時會發生重定向循環。

nash_logged_in方法只是返回TRUE或FALSE的JSON密鑰。任何我會跑到這個重定向循環的原因?

nash_logged_in方法:

if(!function_exists('nash_logged_in')) { 
    function nash_logged_in(){ 
    $url = NASH_OAUTH_URL . '/api/v1/loggedin.json'; 
    $json = file_get_contents($url); 
    $data = json_decode($json); 
    return $data->loggedin; 
    } 
} 

回答

0

如果nash_logged_in()不返回布爾值false或整數0或null,則聲明被評估爲真,因此您的重定向。

在此處發佈nash_logged_in()以查看發生了什麼。

+0

我添加上述 – dennismonsewicz

+0

的方法你知道那的file_get_contents將使用服務器IP地址,而不是客戶端,對吧? – Twisted1919

+0

你是對的...我現在正在改變它使用捲曲 – dennismonsewicz

0

你不會需要使用掛鉤這種方法

柱控制器鉤

你可以只擴展是CI_Controller並在需要的子類的__constructor運行驗證庫被認證。

您當前的控制器有點麻煩,它看起來像一個庫,而不是控制器,如果您在控制器中執行所有操作,則不需要重新實例化超級對象!

但是,我的建議是將所有內容都移到一個庫中(因爲有很多控制器/類依賴於它)。

您的代碼的某些元素對我來說沒有意義,可能是因爲我無法從您發佈的代碼中看到更大的圖片。

雖然(或不)這可能會給你一些食物,不管這是我如何接近它。

應用程序/庫/ authentication.php

class Authentication 
{ 

    protected $allowedClasses = array () ; 
    protected $userId   = null ; 
    protected $nashURL ; 

    const NASH_OAUTH_URL = '' ; 

    public function __construct() 
    { 
     $this->nashURL = static::NASH_OAUTH_URL . '/api/v1/loggedin.json' ; 

     //check for a user id in session 
     //this may not be set yet!! 
     $this->userId = (isset ($this->session->userdata ('id'))) 
      ? $this->session->userdata ('id') 
      : null ; 

     /** Load dependancies * */ 
     $this->load->model ('Authentication_Model') ; 
     $this->load->library ('Session') ; 

    } 

    /** 
    * nashCheckLoginViaCurl 
    * @return boolean 
    */ 
    protected function nashCheckLoginViaCurl() 
    { 
     if (function_exists ('curl_init')) 
     { 
      return show_error ("Enabled CURL please!" , 500) ; 
     } 

     $curl = curl_init() ; 
     curl_setopt_array ($curl , 
          array (
      CURLOPT_URL => $this->nashURL , 
      /** CHECK CURL DOCS FOR FULL LIST OF OPTIONS - FILL THE REST YOURSELF * */ 
     )) ; 

     if (curl_errno ($curl)) 
     { 
      return false ; 
     } 

     $info  = curl_getinfo ($curl) ; 
     $responce = curl_exec ($curl) ; 
     curl_close ($curl) ; 

     //Check and make sure responce is a BOOLEAN and not a STRING 
     //we will typecast below just incase 
     $responce = json_decode ($responce) ; 

     return ($info[ 'http_code' ] == '200' and (bool) $responce->loggedin === true) 
      ? true 
      : false ; 

    } 

    /** 
    * verifyAccess 
    * @param CI_Controller $class (Dependancy Injection) 
    * @return Mixed 
    * 
    */ 
    public function verifyAccess (CI_Controller $class) 
    { 
     //Is there a userId in the session 
     //ie: is user logged In 
     if (is_null ($this->userId) or ! (int) $this->userId) 
     { 
      return false ; 
     } 

     //grab list of allowed classes 
     $this->allowedClasses = $this->listAllowedClasses() ; 

     //check to see if $class is in list of allowed classes 
     if (! in_array ($class , $this->allowedClasses)) 
     { 
      return false ; 
     } 
     //check to see if nashCheckLoginViaCurl returned true 
     if (! $this->nashCheckLoginViaCurl()) 
     { 
      $this->logout() ; 
      return false ; 
     } 

     //return boolean or $authentication_token based on DB query 
     return $this->Authentication_Model->isUserIdRegistered ($this->userId) ; 

    } 

    /** 
    * logout 
    * @return void 
    */ 
    public function logout() 
    { 
     $this->session->unset_userdata (array ('id' => 0)) ; 
     $this->session->sess_destroy() ; 
     $this->session->sess_start() ; 
     return redirect ('/') ; 

    } 

    /** 
    * listAllowedClasses 
    * MAYBE USE A CONFIG FILE FOR THIS? 
    * @return array 
    */ 
    protected function listAllowedClasses() 
    { 
     return array (
      'user' , 'testing' , 'home' , 'lesson_assets' , 's3_handler' , 'ajax' , 
      'api' , 
      'pages' , 'invite' , 'mail' , 'partner' , 'renew' , 'store' , 'news' , 
      'breathe' , 
      'popup' , 'subscription' , 'lessons' 
      ) ; 

    } 

    /** 
    * Load CI Super object object 
    * 
    * @param string $object 
    * @return object 
    */ 
    public function __get ($object) 
    { 
     return get_instance()->$object ; 

    } 

} 

應用程序/模型/ authentication_model.php

class Authentication_Model extends CI_Model 
{ 

    public function isUserIdRegistered ($uid) 
    { 
     $this->db->select ('authentication_token') 
      ->from ('users') 
      ->where ('id' , $uid) 
      ->where ('authentication_token IS NOT' , 'NULL') 
      ->limit (1) ; 

     $query = $this->db->get() ; 

     return ($query->num_rows() > 0) 
      ? $query->result() 
      : FALSE ; 

    } 

} 

應用/核心/ MY_Controller。PHP

class MY_Controller extends CI_Controller 
{ 

    protected $authentication_token ; 

    public function __construct() 
    { 
     parent::__construct() ; 
     $this->load->library ('authentication') ; 

    } 

    protected function _verifyAccess ($class) 
    { 
     $authorized = $this->authentication->verifyAccess (strtolower ($class)) ; 

     if (! $authorized) 
     { 
      //kill further script execution by returning 
      //redirect url 
      return redirect ('login') ; 
     } 
     else 
     { 
      $this->authentication_token = $authorized ; 
     } 
     return ; //return control back to the controller who called me 

    } 

} 

* 測試不同的控制器 - 模擬柱控制器鉤*

class Some_Controller extends MY_Controller 
{ 

    public function __construct() 
    { 
     parent::__construct() ; 

     $this->_verifyAccess (__CLASS__) ; 

    } 

} 

-

class Another_Controller extends MY_Controller 
{ 

    public function __construct() 
    { 
     parent::__construct() ; 

     $this->_verifyAccess (__CLASS__) ; 

    } 

} 
+0

你的答案是好的,但恕我直言,我認爲鉤解決方案更好,在這裏你必須打電話給每個控制器的_verifyAccess,並且鉤子觸發! – gonzalon

+0

您正面臨着一些不知情的開發人員將來會使用本地控制器並造成安全漏洞的風險。 –