2009-07-11 32 views
24

Tôi đang cung cấp thông tin "nhạy cảm" trong PDF và Bảng tính có thể tải xuống trong phần đăng ký người dùng của trang web.Làm thế nào để bạn yêu cầu đăng nhập cho các tập tin media ở Django

Có cách nào để cho phép xác thực django bảo mật phương tiện này mà không cần phục vụ (và không phải đăng nhập theo cách thủ công bằng xác thực cơ bản)?

Tôi đoán có (ngón tay được chuyển) không một cách để làm điều đó với mã psuedo bên dưới, nhưng nó giúp minh họa tốt hơn mục tiêu cuối cùng.

#urls.py 
(r'^protected_media/(?P<filename>.*)$', 'protected_media') 

#views.py 
from django.contrib.auth.decorators import login_required 

@login_required 
def protected_media(request, filename): 
    # @login_required bounces you out to the login url 
    # if logged in, serve "filename" from Apache 

Trả lời

9

Dường như với tôi rằng phương pháp bạn phác thảo trong mã của bạn sẽ hoạt động. Nó thực sự không khác với bất kỳ tài nguyên được bảo vệ nào khác: quan điểm của bạn có thể phục vụ các tệp từ đĩa, bản ghi từ cơ sở dữ liệu, mẫu được hiển thị hoặc bất kỳ thứ gì. Cũng giống như trình trang trí login_required ngăn chặn truy cập trái phép vào các chế độ xem khác, nó sẽ ngăn chặn quyền truy cập đó vào chế độ xem của bạn phục vụ phương tiện được bảo vệ.

Tôi có thiếu gì đó trong câu hỏi của bạn ở đây không? Xin vui lòng làm rõ nếu đó là trường hợp.

CHỈNH SỬA: Đối với liên kết django doc trong nhận xét của bạn: đó là phương pháp chỉ đơn giản là phân phối bất kỳ tệp yêu cầu nào từ một thư mục cụ thể. Vì vậy, trong ví dụ URL đó như /site_media/foo.jpg, /site_media/somefolder/bar.jpg sẽ tự động tìm kiếm các tệp foo.jpgsomefolder/bar.jpg theo document_root. Về cơ bản, mọi thứ dưới document_root sẽ được cung cấp công khai. Điều đó rõ ràng là không an toàn. Vì vậy, bạn tránh điều đó với phương pháp của bạn.

Nó cũng được coi là không hiệu quả vì django chỉ thêm rất nhiều chi phí không cần thiết khi tất cả những gì bạn cần là một cái gì đó giống như Apache để yêu cầu URL và ánh xạ nó vào một tệp trên ổ cứng. (Bạn không cần phiên django, yêu cầu xử lý, v.v.)

Trong trường hợp của bạn, điều này có thể không phải là một mối quan tâm lớn. Trước tiên, bạn đã bảo đảm chế độ xem. Thứ hai, nó phụ thuộc vào các mẫu sử dụng của bạn. Bạn dự đoán bao nhiêu yêu cầu cho các tệp này? Bạn chỉ sử dụng django để xác thực - điều đó có biện minh cho chi phí khác không? Nếu không, bạn có thể xem xét việc phân phối các tệp đó với Apache và sử dụng nhà cung cấp xác thực. Để biết thêm về vấn đề này, hãy xem tài liệu mod_wsgi:

Có cơ chế tương tự có sẵn dưới mod_python Tôi tin. (Cập nhật: chỉ nhận thấy câu trả lời khác hãy xem câu trả lời của Andre đối với phương pháp mod_python..)

EDIT 2: Đối với các mã cho phục vụ một tập tin Với, vui lòng xem đoạn này:

Phương thức send_file sử dụng FileWrapper, điều tốt để gửi lại các tệp tĩnh lớn (nó không đọc toàn bộ tệp vào bộ nhớ).Bạn sẽ cần phải thay đổi content_type tùy thuộc vào loại tệp bạn đang gửi (pdf, jpg, v.v.).

+0

Xin chào, tôi nên làm rõ rằng tôi đang cố gắng dàn xếp mối quan tâm sau đây từ tài liệu django: http://docs.djangoproject.com/en/dev/howto/static-files/#the-big -fat-disclaimer Nếu dòng mã psuedo này là hợp lệ, bạn hoàn thành nó như thế nào? # nếu đăng nhập, phân phối "tên tệp" từ Apache Cảm ơn! -Tom – TomFuertes

+0

OK; vừa cập nhật câu trả lời. Hi vọng điêu nay co ich. – ars

1

Nếu tôi hiểu chính xác câu hỏi của bạn, bạn muốn hạn chế quyền truy cập vào các tệp không được Django phân phối, ví dụ, với máy chủ Apache?

Những gì bạn sẽ yêu cầu là một số cách để máy chủ Apache này sử dụng Django làm nguồn xác thực.

Điều này django snippet mô tả phương pháp như vậy. Nó tạo ra một handler truy cập trong Django được sử dụng bởi Apache khi một yêu cầu cho một tập tin tĩnh đi kèm trong đó cần phải được bảo vệ:

<Location "/protected/location"> 
      PythonPath "['/path/to/proj/'] + sys.path" 
      PythonOption DJANGO_SETTINGS_MODULE myproj.settings 
     PythonOption DjangoPermissionName '<permission.codename>' 
     PythonAccessHandler my_proj.modpython #this should point to accesshandler 
      SetHandler None 
</Location> 

Hope this helps, đoạn đã được đăng trong một thời gian trước đây, vì vậy mọi thứ có thể có thay đổi giữa các phiên bản Django :)

3

Phục vụ hiệu quả hơn các tệp tĩnh qua Django đang được xem xét hiện tại như là một phần của dự án Google SOC. Đối với WSGI, điều này sẽ sử dụng các phần mở rộng wsgi.file_wrapper cho WSGI nếu có, vì nó dành cho mod_wsgi và req.sendfile() nếu sử dụng mod_python. Nó cũng sẽ hỗ trợ trả lại các tiêu đề như 'Vị trí', 'X-Accel-Redirect' và các phần khác, các cơ chế lưu trữ web khác nhau và các giao diện người dùng proxy chấp nhận như một phương tiện phục vụ các tệp tĩnh nơi vị trí được xác định bởi ứng dụng web phụ trợ , không hiệu quả như giao diện người dùng để phục vụ các tệp tĩnh.

Tôi không chắc liệu có một trang dự án cho điều này trong Django wiki ở đâu đó hay không, nhưng các thay đổi mã đang được cam kết vào chi nhánh/soc2009/http-wsgi-cải tiến chi nhánh của kho mã nguồn Django.

Bạn không cần phải chờ đợi một cách nghiêm túc. Nó chỉ là đặt một giao diện sạch sẽ và di động tại chỗ trên các cơ chế khác nhau. Nếu sử dụng nginx làm giao diện người dùng trước Apache/mod_wsgi, bạn có thể sử dụng X-Accel-Redirect ngay bây giờ. Nếu sử dụng Apache/mod_wsgi 3.0 và chế độ daemon, bạn có thể sử dụng Vị trí ngay bây giờ, nhưng cần đảm bảo bạn đã thiết lập đúng Apache. Ngoài ra, bạn có thể triển khai trình bao bọc middleware WSGI của riêng bạn xung quanh ứng dụng Django, tìm kiếm một số tiêu đề phản hồi của riêng bạn để cho biết tệp được trả về và sử dụng wsgi.file_wrapper để trả về thay vì trả lời thực tế từ Django.

BTW, cơ chế móc xác thực được liệt kê cho cả mod_python và mod_wsgi bởi những người khác sẽ sử dụng xác thực cơ sở HTTP, không phải là những gì bạn muốn. Đây là giả định bạn muốn các tập tin được bảo vệ bởi cơ chế đăng nhập dựa trên hình thức Django bằng cách sử dụng cookie và các phiên phụ trợ.

4

Đọc này Django ticket để biết thêm thông tin. Bắt đầu ở dưới cùng để tiết kiệm thời gian. Hình như nó chỉ bỏ lỡ nhận được vào Django 1.2, và tôi giả sử cũng không phải là trong 1.3.

Đối với Nginx, tôi thấy điều này Django snippet tận dụng lợi thế của tiêu đề X-Accel-Redirect, nhưng chưa thử.

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