2012-10-31 21 views
12

Quay lại tháng 5, tôi đã đăng this question. Tôi đang cố gắng làm điều tương tự một lần nữa trên một ứng dụng khác, nhưng tôi đã không tìm thấy một giải pháp cho vấn đề này. Tôi có nhiều thông tin hơn và mã tốt hơn, vì vậy tôi hy vọng các bạn có thể giúp tôi sắp xếp điều này.CakePHP 2.x Auth với hai thông tin đăng nhập riêng biệt

Trường hợp sử dụng: Văn phòng của bác sĩ có trang web với người dùng quản trị. Người dùng đăng nhập thành công với Auth CakePHP qua mô hình UserUsersController.

Các bác sĩ đã giới thiệu các bác sĩ có hồ sơ và hành động hoàn toàn khác nhau. Các bác sĩ cần đăng nhập qua số example.com/physicians/login. Tuy nhiên, đăng nhập này là không với điều này

authError => 'You are not authorized to access that location.'

Đây là mã của tôi trong AppController:

class AppController extends Controller { 
public $helpers = array('Form', 'Html', 'Time', 'Session', 'Js' => array('Jquery')); 

public $components = array(
    'Session', 
    'Auth' => array(
     'autoRedirect' => false, 
     'authorize' => 'Controller' 
    ) 
); 

public function beforeFilter() { 
    $this->Auth->allow('index', 'view', 'edit', 'display', 'featured', 'events', 'contact', 'signup', 'search', 'view_category', 'view_archive', 'addComment', 'schedule', 'login'); 
} 

}

Và đây là của tôi UsersController rằng đang làm việc:

class UsersController extends AppController { 

public $components = array(
    'Auth' => array(
     'authenticate' => array(
      'Form' => array(
       'userModel' => 'User', 
       'fields' => array(
        'username' => 'username', 
        'password' => 'password' 
       ) 
      ) 
     ), 
     'loginRedirect' => array('controller' => 'users', 'action' => 'admin'), 
     'logoutRedirect' => array('controller' => 'pages', 'action' => 'index'), 
     'loginAction' => array('controller' => 'users', 'action' => 'login'), 
     'sessionKey' => 'Admin' 
    ) 
); 


public function beforeFilter() { 
    parent::beforeFilter(); 
    $this->Auth->allow('add', 'login', 'logout'); 
} 

function isAuthorized() { 
    return true; 
} 

public function login() { 
    if ($this->request->is('post')) { 
     if ($this->Auth->login()) { 
      $this->redirect($this->Auth->redirect()); 
     } else { 
      $this->Session->setFlash(__('Invalid username or password, try again')); 
     } 
    } 
} 

public function logout() { 
    $this->Session->destroy(); 
    $this->redirect($this->Auth->logout()); 
} 

Đây là sốcủa tôimã mà KHÔNG làm việc:

class PhysiciansController extends AppController { 

public $components = array(
    'Auth' => array(
     'authenticate' => array(
      'Form' => array(
       'userModel' => 'Physician', 
       'fields' => array(
        'username' => 'username', 
        'password' => 'password' 
       ) 
      ) 
     ), 
     'loginRedirect' => array('controller' => 'physicians', 'action' => 'dashboard'), 
     'logoutRedirect' => array('controller' => 'pages', 'action' => 'index'), 
     'loginAction' => array('controller' => 'physicians', 'action' => 'login'), 
     'sessionKey' => 'Physician' 
    ) 
); 

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

    $this->Auth->authorize = array(
     'Actions' => array(
      'userModel' => 'Physician', 
      'actionPath' => 'physicians' 
     ) 
    ); 

    $this->Auth->allow('login', 'logout'); 
// $this->Session->write('Auth.redirect','/physicians/index'); 
} 

function isAuthorized() { 
    return true;  
} 

public function login() { 
    if ($this->request->is('post')) { 
     if ($this->Auth->login()) { 
      $this->redirect(array('controller' => 'physicians', 'action' => 'dashboard')); 
     } else { 
      $this->Session->read(); 
      debug($this->Auth); 
      $this->Session->setFlash(__('Invalid username or password, try again')); 
     } 
    } 
} 

public function logout() { 
    $this->Session->destroy(); 
    $this->redirect($this->Auth->logout()); 
} 

tôi thực sự không muốn bắt đầu lại và chuyển sang ACL - Tôi không chắc đó là cần thiết để chỉ hai thông tin đăng nhập. Sự giúp đỡ được đánh giá cao!

EDIT: Câu trả lời của Joshua bên dưới là tuyệt vời và cực kỳ hữu ích. Tôi thực hiện nó, nhưng tôi vẫn nhận được một lỗi trái phép khi tôi cố gắng đăng nhập như một bác sĩ thông qua/phys/physican/login (tiền tố/điều khiển/hành động). Thiết lập Quản trị hoạt động tốt. Dưới đây là đoạn code debug khi tôi cố gắng đăng nhập:

object(AuthComponent) { 
    components => array(
    (int) 0 => 'Session', 
    (int) 1 => 'RequestHandler' 
) 
authenticate => array(
    'Form' => array(
     'userModel' => 'Physician' 
    ) 
) 
authorize => false 
ajaxLogin => null 
flash => array(
    'element' => 'default', 
    'key' => 'auth', 
    'params' => array() 
) 
loginAction => array(
    'controller' => 'physicians', 
    'action' => 'phys_login' 
) 
loginRedirect => null 
logoutRedirect => '/' 
authError => 'You are not authorized to access that location.' 
allowedActions => array() 
request => object(CakeRequest) { 
    params => array(
     'prefix' => '*****', 
     'plugin' => null, 
     'controller' => 'physicians', 
     'action' => 'phys_login', 
     'named' => array(), 
     'pass' => array(), 
     'phys' => true, 
     '_Token' => array(
      'key' => 'ad1ea69c3b2c7b9e833bbda03ef18b04079b23c3', 
      'unlockedFields' => array() 
     ), 
     'isAjax' => false 
    ) 
    data => array(
     'Physician' => array(
      'password' => '*****', 
      'username' => 'deewilcox' 
     ) 
    ) 
    query => array() 
    url => 'phys/physicians/login' 
    base => '' 
    webroot => '/' 
    here => '/phys/physicians/login' 
} 
response => object(CakeResponse) { 

} 
settings => array() 

}

Trả lời

19

OK Tôi đã có một cách để làm điều đó. Bạn biết về định tuyến tiền tố? Nếu không, hãy đọc câu trả lời của tôi ở đây: CakePHP/MVC Admin functions placement Câu trả lời đó mô tả cách thiết lập một tiền tố định tuyến đơn ('quản trị'). Nhưng bạn có thể có bất kỳ số - chỉ cần như thế này:

Configure::write('Routing.prefixes', array('admin','phys','member','user')); 
// now we have admin, phys, member and user prefix routing enabled. 

Những gì bạn có thể làm là có tất cả các phương pháp của bác sĩ sử dụng 'admin' tiền tố định tuyến, và tất cả các bác sĩ phương pháp sử dụng tiền tố định tuyến 'Phys.

Vì vậy, dưới đây là mã tôi đã tấn công với nhau khá nhanh chóng, vì vậy nó có thể không hoàn hảo nhưng nó sẽ hiển thị khái niệm.Ở đây nó là trong mã giả cho phương pháp lọc trước của bộ điều khiển ứng dụng của bạn:

if (USER IS TRYING TO ACCESS AN ADMIN PREFIXED METHOD) { 
    Then use the users table for auth stuff 
} else if (USER IS TRYING TO ACCESS A PHYS PREFIXED METHOD) { 
    Then use the physicians table for auth stuff 
} else { 
    It's neither an admin method, not a physicians method. So just always allow access. Or always deny access - depending on your site 
} 

Đây là mã điều khiển ứng dụng của tôi:

App::uses('Controller', 'Controller'); 

class AppController extends Controller { 

    public $components = array('Security','Cookie','Session','Auth','RequestHandler'); 
    public $helpers = array('Cache','Html','Session','Form'); 

    function beforeFilter() { 

     if ($this->request->prefix == 'admin') { 
      $this->layout = 'admin'; 
      // Specify which controller/action handles logging in: 
      AuthComponent::$sessionKey = 'Auth.Admin'; // solution from https://stackoverflow.com/questions/10538159/cakephp-auth-component-with-two-models-session 
      $this->Auth->loginAction = array('controller'=>'administrators','action'=>'login'); 
      $this->Auth->loginRedirect = array('controller'=>'some_other_controller','action'=>'index'); 
      $this->Auth->logoutRedirect = array('controller'=>'administrators','action'=>'login'); 
      $this->Auth->authenticate = array(
       'Form' => array(
        'userModel' => 'User', 
       ) 
      ); 
      $this->Auth->allow('login'); 

     } else if ($this->request->prefix == 'phys') { 
      // Specify which controller/action handles logging in: 
      AuthComponent::$sessionKey = 'Auth.Phys'; // solution from https://stackoverflow.com/questions/10538159/cakephp-auth-component-with-two-models-session 
      $this->Auth->loginAction = array('controller'=>'users','action'=>'login'); 
      $this->Auth->logoutRedirect = '/'; 

      $this->Auth->authenticate = array(
       'Form' => array(
        'userModel' => 'Physician', 
       ) 
      ); 
     } else { 
      // If we get here, it is neither a 'phys' prefixed method, not an 'admin' prefixed method. 
      // So, just allow access to everyone - or, alternatively, you could deny access - $this->Auth->deny(); 
      $this->Auth->allow();   
     } 
    } 

    public function isAuthorized($user){ 
     // You can have various extra checks in here, if needed. 
     // We'll just return true though. I'm pretty certain this method has to exist, even if it just returns true. 
     return true; 
    } 

} 

Lưu ý các dòng:

AuthComponent::$sessionKey = 'Auth.Admin'; // solution from https://stackoverflow.com/questions/10538159/cakephp-auth-component-with-two-models-session 

AuthComponent::$sessionKey = 'Auth.Phys'; // solution from https://stackoverflow.com/questions/10538159/cakephp-auth-component-with-two-models-session 

Điều gì điều đó cho phép một người được đăng nhập với tư cách là cả bác sĩ và quản trị viên, trong một trình duyệt mà không can thiệp vào phiên của nhau. Bạn có thể không cần nó trong trang web trực tiếp, nhưng nó chắc chắn tiện dụng trong khi thử nghiệm.

Bây giờ, trong các bộ điều khiển tương ứng, bạn sẽ cần các phương thức đăng nhập/đăng xuất thẳng về phía trước, với tiền tố thích hợp.

Vì vậy, đối với quản trị prefixing, trong điều khiển người dùng của bạn:

public function admin_login() { 
    if ($this->request->is('post')) { 
     if ($this->Auth->login()) { 
      return $this->redirect($this->Auth->redirect()); 
     } else { 
      $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth'); 
     } 
    } 
} 

public function admin_logout() { 
    $this->Session->setFlash('Successfully Logged Out'); 
    $this->redirect($this->Auth->logout()); 
} 

Và trong điều khiển các bác sĩ của bạn:

public function phys_login() { 
    if ($this->request->is('post')) { 
     if ($this->Auth->login()) { 
      return $this->redirect($this->Auth->redirect()); 
     } else { 
      $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth'); 
     } 
    } 
} 

public function phys_logout() { 
    $this->Session->setFlash('Successfully Logged Out'); 
    $this->redirect($this->Auth->logout()); 
} 

Như tôi đã nói, đó là tất cả các mã tôi bị hack cùng nhau khá nhanh chóng, vì vậy nó có thể không hoạt động đúng nguyên văn, nhưng nó sẽ hiển thị khái niệm. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi.

+0

Cảm ơn rất nhiều cho điều này - bạn đá. Tôi thực hiện ngày hôm nay và không gặp rắc rối với tiền tố quản trị và điều khiển người dùng. Tuy nhiên, các bác sĩ điều khiển vẫn còn cho tôi rằng cùng một "Bạn không được ủy quyền" lỗi. Vì vậy, hầu như không có gì thay đổi. Tôi sẽ đăng các mã gỡ lỗi ở trên nếu điều đó giúp. – deewilcox

+0

Vì vậy, bạn nhận được 'Tên người dùng hoặc mật khẩu không hợp lệ, hãy thử lại' hoặc bạn không nhận được điều đó chút nào và chỉ nhận được 'Bạn không được phép truy cập vào vị trí đó.'? Đó là để nói, có "if ($ this-> Auth-> login()) {" của bạn vượt qua, và sau đó bạn chỉ nhận được một vấn đề về chuyển hướng sau đăng nhập? Hay dòng đó thất bại? –

+0

Tôi nhận được lỗi "Bạn không được ủy quyền". Nếu tôi chuyển '($ this-> request-> data)' vào, nó hoạt động. Tôi đã thử nghiệm bằng cách sử dụng tên người dùng và mật khẩu không hợp lệ với '$ this-> Auth-> login ($ this-> request-> data);' và thông tin đăng nhập không thành công (nếu cần) nếu tên người dùng hoặc mật khẩu sai. – deewilcox

0

Thay vì

$this->Session->write('Auth.redirect','/physicians/index'); 

bạn nên sử dụng

setcookie("keys", value);