2009-12-11 23 views
5

Tôi (cho đến nay) đã xử lý các phiên của người dùng với các cookie và các mục cơ sở dữ liệu phía máy khách.xử lý an toàn các phiên của khách hàng trong PHP

Khi người dùng đăng nhập, tôi tạo một guid và đặt nó vào một cookie trên máy tính của khách hàng. Sau đó, tôi tạo một mục trong bảng MySQL 'phiên' và thêm vào đó guid, địa chỉ ip, tên người dùng, đặc quyền, v.v. Sau đó khi người dùng truy cập trang, tôi kiểm tra xem có cookie phiên không. nếu có, tôi kiểm tra cơ sở dữ liệu cho guid trong cookie và đảm bảo địa chỉ ip khớp với nhau. Nếu có thì người dùng sẽ đăng nhập với phần còn lại của thông tin trong bảng db. Nếu có điều gì đó sai (địa chỉ ip xấu, phiên hết hạn, v.v.), tôi xóa mục nhập cơ sở dữ liệu và xóa cookie guid.

Tôi chưa từng sử dụng $ _SESSION toàn cầu trước đây.

Cách thực hành tốt của tôi hay tôi cần phải nghĩ lại cách tôi xử lý việc này?

+1

Bạn đang sáng tạo lại bánh xe bạn của tôi –

Trả lời

7

Nghe có vẻ như bạn đã có những điều cơ bản bảo hiểm. Tuy nhiên, nếu bạn đang làm tất cả theo cách thủ công, thì bạn có hiệu quả chỉ cần triển khai $_SESSION của riêng mình và không tận dụng được thực tế là nó có thể làm tất cả những gì cho bạn.

Nếu bạn muốn sử dụng cơ sở dữ liệu để xử lý một phiên, bạn có thể ghi đè lên phiên xử lý mặc định của riêng mình. Hãy xem session_set_save_handler(). Tôi làm điều này trong các ứng dụng của tôi.

class SessionHandler 
{ 

    public function open($save_path, $session_name) 
    { 
     $this->sessionName = $session_name; 
    return(true); 
    } 
    public function close() { 
     //stuff 
    } 

    public function read($id) { 
     $expiretime = date("Y-m-d H:i:s",time() - $this->maxLifeTime); 
     $sql = "SELECT * FROM sessions where sessionid='".$this->db->escapeData($id)."' AND lastupdated>='".$expiretime."' LIMIT 1"; 
    $result = $this->db->query($sql); 
     //etc. 
    } 

    //etc. 

    public function setAsSessionHandler() 
    { 
    session_set_save_handler(
     array($this,'open'), 
     array($this,'close'), 
     array($this,'read'), 
     array($this,'write'), 
     array($this,'destroy'), 
     array($this,'gc') 
    ); 
    } 
} 

$sessionHandler = new SessionHandler(); 
$sessionHandler->setAsSessionHandler(); 

Bạn có thể có tất cả chức năng bạn đã mô tả chính mình bằng cách sử dụng tính năng này, nhưng vẫn có sức mạnh $ _SESSION để làm điều đó cho bạn. Ví dụ, nếu bạn muốn thêm một kiểm tra IP để xem phiên đó vẫn còn hợp lệ trước khi bạn bắt đầu nó, bạn có thể thêm rằng đó là một phần của chức năng "mở". Nếu bạn muốn ghi dữ liệu phiên vào mười cơ sở dữ liệu khác nhau (không phải là bạn muốn), bạn có thể thực hiện điều này trong hàm 'write'.

Các chức năng này đều được sử dụng dựa trên cách bạn sử dụng $ _SESSION và bằng cách đặt chúng vào một lớp đơn giản, bạn có thể quản lý cách hoạt động rất hiệu quả.

Bạn sẽ thấy rằng id phiên là thông số được chuyển đến các chức năng đọc/ghi/hủy và bạn vẫn sẽ quản lý theo cách tương tự bằng cách sử dụng thường trình tạo GUID của mình.Tuy nhiên, bạn có thể gắn kết quá trình tạo và kiểm tra vào lớp trình quản lý phiên này và chỉ đơn giản là có hàm open() làm chúng. Tập trung, không ồn ào, không ồn ào.

1

Cách bạn đang làm bây giờ là tốt nếu bạn bằng cách nào đó cần liên kết người dùng hiện tại với thông tin cơ sở dữ liệu khác.

Sử dụng phiên là cách ưu tiên để làm điều đó để đơn giản. Tôi đề nghị bạn đọc một chút về nó trên www.php.net/sessions và làm cho tâm trí của bạn từ đó. Nó rất dễ sử dụng, nhưng nó ít linh hoạt hơn so với sử dụng một bảng cơ sở dữ liệu. Bạn vẫn có thể đặt tất cả các giá trị bạn cần, nhưng sau đó bạn phải tìm nạp chúng và chèn chúng vào truy vấn bất cứ khi nào bạn cần sử dụng chúng cho các hoạt động cơ sở dữ liệu.

+0

đó là một điểm tốt, nhưng tôi nghĩ rằng lớp xử lý phiên zombats làm cho phần cơ sở dữ liệu của các phiên liền mạch hơn một chút. –

1

Tôi nghĩ bạn đang đi đúng hướng. Nó thực sự sẽ phụ thuộc vào các yêu cầu bảo mật của ứng dụng của bạn. Bạn có thể nghĩ $ _SESSION rất giống với $ _COOKIE: là một cơ chế để cung cấp trạng thái giữa các lần làm mới trang. Trong ngữ cảnh này, danh tính của người dùng của bạn. Cơ sở dữ liệu của bạn nên cung cấp thêm cơ chế xác thực. Những điều có thể xác định duy nhất người dùng của bạn. Một giả thiết điển hình là địa chỉ IP, nhưng điều gì sẽ xảy ra nếu một ai đó thay đổi IP? Tác nhân người dùng là một khả năng khác nhưng những mùi hương này rất độc đáo.

tôi sẽ khuyên bạn nên xem tại địa chỉ: http://php.net/manual/en/session.security.php

+0

Tôi nghĩ rằng địa chỉ IP đủ tốt, đặc biệt là vì hầu hết mọi người đều ở đằng sau các router, và IP thường không làm mới (trừ trải nghiệm của tôi) trừ khi router được đặt lại, thường cùng với một số cơ chế bên trong để làm mới IP. Ngoài ra, ngay cả khi làm mới IP của người dùng là một yếu tố nghiêm trọng, tất cả điều đó có nghĩa là người dùng phải đăng nhập lại - cộng với việc triển khai của riêng tôi, tôi thường làm cho phiên hết hạn trong khoảng ba hoặc bốn giờ. –

+0

Đó là tất cả rất đúng sự thật. Tôi đã suy nghĩ nhiều hơn về khách hàng di động. Nếu bạn là trang web sẽ được truy cập bằng điện thoại, nếu người đó đang di chuyển, có khả năng thay đổi IP cao hơn nhiều. Tuy nhiên, đây thường là một phần nhỏ lưu lượng truy cập web cho hầu hết mọi người. – Brad

+0

Ngoài ra, nếu bạn đang tìm kiếm tích hợp $ _SESSION liền mạch với cơ sở dữ liệu của bạn, hãy nhìn vào thành phần Zend_Auth của khung công tác Zend. – Brad

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