2010-09-29 45 views
5

Tôi đã tạo đăng ký và đăng nhập cho trang web của mình và tất cả xác thực đều hoạt động tốt cho cả đăng ký và đăng nhập. Sau khi người dùng cung cấp thông tin đăng nhập hợp lệ, anh/cô ấy đã đăng nhập vào khu vực thành viên với một thông báo chào mừng có tên Hello first_name last_name .. về cơ bản họ và tên được lấy từ cơ sở dữ liệu.Phương pháp hay nhất để hạn chế các trang cụ thể cho người dùng đã đăng nhập chỉ trong Codeigniter?

Bất kỳ điều gì tôi muốn làm là giới hạn khu vực thành viên chỉ cho những người dùng đã đăng nhập. Bất kỳ ai khác sẽ được chuyển hướng đến trang chủ hoặc trang đăng nhập hoặc khi nào tôi quyết định họ nên được chuyển hướng đến.

Tôi sử dụng ci_sessions được lưu trữ trong bảng "ci_sessions" trong cơ sở dữ liệu của tôi. Session_id, ip_address, user_agent, last_activity và user_data là các cột. Vì vậy, tôi đoán đó là một số hình thức hình thức bảo mật hơn là có một cookie được lưu trữ trên trình duyệt người dùng một mình có nhiều hơn nữa.

Dù sao ngay bây giờ để ngăn bất kỳ ai khác ngoài những người dùng đã đăng nhập truy cập vào khu vực thành viên trang web của tôi, ví dụ: http://mysite.com/member_area tôi sử dụng một đơn giản nếu tuyên bố trong điều khiển của tôi đối với khu vực thành viên:

if (! $this->session->userdata('first_name')) 
    { 
    redirect('login'); 
} 

này kiểm tra để xem liệu người đang cố gắng truy cập vào trang khu vực thành viên có một số loại dữ liệu được lưu trữ trong user_data trong bảng ci_sessions của tôi chẳng hạn như first_name và nếu như vậy cho phép họ truy cập vào trang có nghĩa là họ phải đăng nhập và vẫn có phiên hoạt động.

Nếu không tìm thấy gì trong cơ sở dữ liệu, chúng sẽ được chuyển hướng đến trang đăng nhập trang web. Những gì tôi muốn biết là nếu có một cách tốt hơn để làm điều này? Có phải cách tôi đang làm bây giờ đủ an toàn không?

Dưới đây là mã mô hình của tôi:

<?php 
class Current_User { 

    private static $user; 

    private function __construct() {} 

    public static function user() { 

     if(!isset(self::$user)) { 

      $CI =& get_instance(); 
      $CI->load->library('session'); 

      if (!$user_id = $CI->session->userdata('user_id')) { 
       return FALSE; 
      } 

      if (!$u = Doctrine::getTable('User')->find($user_id)) { 
       return FALSE; 
      } 

      self::$user = $u; 
     } 

     return self::$user; 
    } 


    public static function login($email, $password) { 

     // get User object by email 
     if ($u = Doctrine::getTable('User')->findOneByEmail($email)) { 


      // to ge the mutated version of the input password 
      $u_input = new User(); 
      $u_input->password = $password; 

      // password match 
      if ($u->password == $u_input->password) { 


       $CI =& get_instance(); 
       $CI->load->library('session'); 
       $CI->session->set_userdata('user_id',$u->id); 
       $CI->session->set_userdata('username',$u->username); 
       $CI->session->set_userdata('first_name',$u->first_name); 
       $CI->session->set_userdata('last_name',$u->last_name); 

       self::$user = $u; 

       return TRUE; 
      } 

      unset($u_input); 
     } 

     // login failed 
     return FALSE; 

    } 


    public function __clone() { 
     trigger_error('No duplicates allowed.', E_USER_ERROR); 
    } 

} 

Tất cả lời khuyên của bạn được đánh giá cao.

CẬP NHẬT

Làm thế nào về việc thêm này để mô hình của tôi

$CI->session->set_userdata('logged_in', 'TRUE'); 

này về cơ bản thêm "logged_in" để dữ liệu của tôi sử dụng trong phiên làm việc trong DB với giá trị "TRUE". trong bộ điều khiển của tôi cho "khu vực thành viên" của tôi, tôi đã chỉnh sửa câu lệnh if để nói điều này:

if (! $this->session->userdata('logged_in')==TRUE) 
{ 
redirect('login'); 

}

Nếu mục không tồn tại ", mà nó sẽ không nếu một isn người dùng t đã đăng nhập "rồi FALSE sẽ được trả lại và người dùng sẽ được chuyển hướng đến trang đăng nhập

Bạn nghĩ sao?

hoặc tôi thậm chí có thể làm cho TRUE một cái gì đó bí mật như dsb453rerfksdhbdsks322 ví dụ. Một cái gì đó ngẫu nhiên.

Trả lời

10

Bạn đã chạm vào móng trên đầu, nhưng có một cách hiệu quả hơn một chút để thực hiện điều đó.

Mở rộng điều khiển cơ bản, một cách (i tin rằng ban đầu vạch ra bởi Phil Sturgeon) nhưng tôi sẽ tóm tắt ở đây:

Xem this article cho một rất sâu sắc ghi lên.

nhưng trong bản chất:

<?php 
class MY_Controller extends Controller 
{ 
    function __construct() 
    { 
     parent::Controller(); 
     if (! $this->session->userdata('first_name')) 
     { 
      redirect('login'); // the user is not logged in, redirect them! 
     } 
    } 
} 

vì vậy bây giờ nếu bạn muốn hạn chế quyền truy cập, chỉ cần:

class Secret_page extends MY_Controller { 

// your logged in specific controller code 
} 

và bộ điều khiển mở rộng sẽ tự động kiểm tra nếu người dùng đang đăng nhập trong constructor.

làm cách nào, tôi có thể đặt user_id làm giá trị để kiểm tra xem tập hợp của nó hay có thể là "nhóm" của người dùng - sau đó bạn có thể nhận quyền của người dùng và các cấp truy cập khác nhau trong hệ thống của mình.

hy vọng điều này sẽ giúp ích một chút.

chỉnh sửa

Thêm phần này vào application/config.php

/* 
| ------------------------------------------------------------------- 
| Native Auto-load 
| ------------------------------------------------------------------- 
| 
| Nothing to do with cnfig/autoload.php, this allows PHP autoload to work 
| for base controllers and some third-party libraries. 
| 
*/ 
function __autoload($class) 
{ 
    if(strpos($class, 'CI_') !== 0) 
    { 
     @include_once(APPPATH . 'core/'. $class . EXT); 
    } 
} 

Như bạn đang sử dụng CI 2.0, bạn sẽ cần phải đặt MY_Controllers bên trong Application/CORE chứ không phải là thư viện.

My Application/Core Trông một chút như:

Admin_Controller.php 
MY_Controller.php 
Public_Controller.php 
+0

Yea cảm ơn rất nhiều. Tôi sẽ đọc bài viết của Phil Sturgeon để hiểu rõ hơn. Một điều tôi đã nhận thấy là ngay cả khi tôi không đăng nhập id phiên, user_agent, ip, last_active được lưu trữ/cập nhật trong cơ sở dữ liệu. Bây giờ tôi có thể tưởng tượng hàng triệu người đang duyệt trang web mà không đăng nhập. Điều này có tệ không? Không phải nó chỉ ghi lại thông tin của người dùng đăng nhập? nếu không phải là có một cách tôi có thể làm cho nó để tiêu diệt dữ liệu này hoặc không đăng nhập nó ở tất cả nếu người dùng không đăng nhập? – LondonGuy

+0

Lỗi nghiêm trọng: Lớp 'MY_Controller' không được tìm thấy trong ... Tôi nghĩ đó là lỗi codeignitet 2.0 – LondonGuy

+0

nada, bạn cần sử dụng ma thuật tự động tải xuống PHP5. xem bài viết đã chỉnh sửa của tôi – Ross

0

tôi sử dụng một cái gì đó như:

$user_session = $this->model_user_lite->Session_Check(); 
    if ($user_session == FALSE) 
    { 
     redirect('main/about'); 
     exit(); 
    } 
    $data['auth'] = $user_session; 
    $user_id = $this->model_user_lite->Session_UserID(); 

để bảo vệ không phải là điều khiển nhưng các chức năng của riêng mình, mà trong ý kiến ​​của tôi là hơn hiệu quả. Mã này là khá tự giải thích, tuy nhiên tôi đặt việc kiểm tra phiên quá:

function Session_Check ($return_link = FALSE) 
{ 

    $auth = $this->session->userdata('logged_in'); 
    if ($auth == FALSE) 
    { 
     $return_value = FALSE; 
    } 
    else 
    { 
     $return_value = TRUE; 
    } 

    return $return_value; 

} 

nên nơi người dùng đăng nhập vào, chúng ta chỉ cần đặt các userdata "logged_in" TRUE và kiểm tra xem nó bất cứ khi nào chúng ta muốn.

Tôi hy vọng điều đó sẽ hữu ích!

0

Tôi không nghĩ rằng đó là một công việc điều khiển để thực hiện bảo mật, nó chỉ nên kiểm tra nó. Bạn có thể mã logic xác thực của mình vào thư viện. Tiếp theo, tự động tải thư viện đó. Trong các phương pháp điều khiển đang phục vụ nội dung được bảo vệ, bạn có thể chỉ cần thực hiện việc này:

$ this-> auth-> restrict();

Các vấn đề liên quan