2012-05-24 25 views
8

Tôi đang làm việc để phát triển một trang web cho phép khách hàng đăng nhập và xem nhiều PDFs được lưu trên máy chủ. Các tệp PDF này sẽ là duy nhất cho ứng dụng khách và không thể truy cập được bởi người không đăng nhập. Việc tải các tệp lên máy chủ không phải là vấn đề, tôi không chắc chắn về cách phân phát chúng cho người dùng cuối.Tạo một Máy chủ Lưu trữ Tệp Bảo mật cho các tệp PDF

Tôi đã triển khai loại dữ liệu này từ dữ liệu SQL servers thay vì tệp, vì vậy tôi không hoàn toàn chắc chắn cách hiệu quả nhất để thực hiện điều này.

Trang web có trên LAMP và trải nghiệm tối thiểu của tôi là ở PHP (nhưng nếu khung hoặc ngôn ngữ khác sẽ giúp việc này dễ dàng hơn, tôi có thể tìm hiểu).

Tôi có thể đang ở trong đầu nhưng tôi thường sáng, vì vậy mọi đầu vào đều tuyệt vời.

Trả lời

9

Đặt tệp bên ngoài webroot. Sau đó, bằng cách sử dụng PHP vượt qua các tập tin mặc dù một kịch bản. Bằng cách đó, không ai có thể liên kết trực tiếp đến tập tin và bỏ qua các điều khiển của bạn. (Đương nhiên đảm bảo rằng tập lệnh thực hiện điều này chỉ sau khi xác minh người dùng có quyền truy xuất tệp đó).

mẫu PHP:

<?php 
    session_start(); 
    if (!isset($_SESSION['authenticated'])) { 
     exit; 
    } 
    $file = '/path/to/file/outside/www/secret.pdf'; 

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename=' . basename($file)); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . filesize($file)); 
    ob_clean(); 
    flush(); 
    readfile($file); 
    exit; 
?> 
+0

Không nên 'session_start();' được tải? Tôi lấy nó mà nó phải làm việc với các phiên. –

+0

Trên thực tế, có, nó phải được. Tôi đã rất tập trung vào khái niệm cốt lõi mà tôi đã không cung cấp một ví dụ thực sự hoàn chỉnh. Sửa chữa ngay bây giờ ... –

+0

Chỉ cần kiểm tra ;-) –

4

Cách đơn giản là để cung cấp cho những tập tin dài tên tập tin ngẫu nhiên (ví dụ, 20 ký tự ngẫu nhiên). Về mặt kỹ thuật, mọi người có thể truy cập chúng, nhưng sẽ không thể đoán được URL, vì vậy chỉ những người được ủy quyền mới có quyền truy cập.

Hoặc John Conde đã vạch ra một cách để phân phát tệp từ tập lệnh PHP. Nó sẽ phải chịu một hình phạt hiệu suất nhỏ, nhưng sẽ an toàn như mã của bạn. Điều duy nhất tôi có thể thêm là nếu bạn không thể đặt chúng bên ngoài webroot, thì bạn có thể sử dụng .htaccess để ngăn người khác truy cập trực tiếp vào các tệp.

+1

Tôi sẽ đề nghị GUID. Điều này vẫn còn có vấn đề mà tôi có thể ping máy chủ cho đến khi tôi nhận được một cái gì đó thú vị, mặc dù bạn có thể làm cho cơ hội thành công biến mất nhỏ. Tôi hỗ trợ việc sử dụng .htaccess để chặn truy cập vào thư mục. – zebediah49

+1

@ zebediah49 - Đó là một khả năng, nhưng [có những cạm bẫy] (http://blogs.msdn.com/b/oldnewthing/archive/2012/05/23/10309199.aspx) mà bạn nên biết. Đơn giản chỉ cần tạo một chuỗi ngẫu nhiên là an toàn hơn. Và, nếu bạn muốn chắc chắn 110%, hãy sử dụng trình tạo số ngẫu nhiên mạnh mã hóa. –

+0

Rất thú vị, cảm ơn. Tôi đã chọn GUID cho độ dài, nhưng tôi vẫn sẽ tránh sử dụng các URL có thể truy cập công cộng, nhưng đó là một điểm rất tốt. – zebediah49

2

John đã đăng đúng cách chính để thực hiện, vì vậy tôi thêm phương án thay thế (có thể kém): Phục vụ nó từ cơ sở dữ liệu. Chỉ cần có một cột BLOB cho tệp PDF và đọc/lưu trữ dữ liệu tệp từ cơ sở dữ liệu. Bạn sẽ kết thúc với một bảng khá lớn, nhưng nó sẽ làm việc. Phục vụ nó yêu cầu thiết lập cùng một header() s như John được đăng, bạn chỉ cần gửi dữ liệu từ DB thay vì từ tệp.

Điều này có lợi thế là không phải đảm bảo bạn không có xung đột tên tệp, v.v.

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