urls.py
对我进行了一些测试,但我的总体问题是:这是保护某些文件从已登录用户之外保护某些文件的不错的方法吗?
Edit:此外,目前我不太关心Django服务文件,因为相关文件不是很大,而且此应用程序不需要扩展(仅内部HR使用)。
i我面对同样的问题,但有一些不同的方案,只能保护一些媒体URL才能访问特定用户(已验证的用户), 其他媒体URL应该是公开的(任何人都应该查看),经过许多搜索 /测试,我最终找到了与我一起生产的解决方案,
我想与您分享我的经验。 首先,这是我的场景
任何媒体URL都以“ Media_url/Ticket/”开头。任何其他媒体URL都可以通过任何人访问它。
这是我的解决方案:
IAMA在Almalinux 9服务器上使用Django与Apache Weberver。
import re
from . import views
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth.decorators import login_required
from django.shortcuts import HttpResponseRedirect
from django.urls import path
from django.views.static import serve
from django.contrib.auth import views as auth_views
@login_required
def serve_protected_media(request, path, document_root=None, show_indexes=False):
return serve(request, path, document_root, show_indexes)
def protected_serve(request, path, document_root=None, show_indexes=False):
if re.match(r'^protected', path):
return serve_protected_media(request, path, document_root, show_indexes)
else:
return serve(request, path, document_root, show_indexes)
urlpatterns = [
path('', views.index, name='site_index'),
path('admin/', admin.site.urls),
path('hr/', include('hr.urls')),
path('accounts/login/', auth_views.login, name='login'),
path('accounts/logout/', auth_views.logout, name='logout', kwargs={'next_page': '/'}),
] + static(settings.MEDIA_URL, protected_serve, document_root=settings.MEDIA_ROOT)
main url.py:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_root_dir/')
MEDIA_URL = '/media_url/'
urlpatterns = [
# .....
path('media_url/ticket/ticket_files/<str:file_name>/', ProtectedMediaView.as_view(), name='protected_media'),
path('media_url/ticket/ticket_replay_files/<str:file_name>/', ProtectedMediaView.as_view(), name='protected_media')
]
class ProtectedMediaView(APIView):
def get(self, request, file_name, *args, **kwargs):
# Ensure the user is authenticated (the permission classes do this)
if request.user.is_authenticated:
# Check if the file is from the ticket files or ticket reply files
if 'ticket_files' in request.path:
# Lookup for ticket file
ticket_file = get_object_or_404(TicketFiles, ticket_file_ticket_file__icontains=file_name)
ticket = ticket_file.ticket_file_ticket
file_path = ticket_file.ticket_file_ticket_file.path
elif 'ticket_replay_files' in request.path:
# Lookup for ticket reply file
reply_file = get_object_or_404(TicketReplyFiles, ticket_replay_file__icontains=file_name)
ticket = reply_file.ticket_replay_file_ticket_replay.ticket_replay_ticket
file_path = reply_file.ticket_replay_file.path
else:
return HttpResponseForbidden("Invalid file path")
# Permission check: Only allow access to the file if the user is a superuser, staff, or the ticket owner
if request.user.is_superuser or request.user.is_staff or ticket.ticket_user == request.user:
try:
# Determine the file's MIME type
mime_type, _ = guess_type(file_path)
if not mime_type:
mime_type = 'application/octet-stream' # Default if type cannot be guessed
# Open the file and send it as a response
response = FileResponse(open(file_path, 'rb'))
response['Content-Type'] = mime_type # Set appropriate content type
return response
except FileNotFoundError:
return HttpResponseForbidden("File not found")
else:
return HttpResponseForbidden("You do not have permission to access this file")
else:
return HttpResponseForbidden("Authentication required")
-
过程将如何工作
Apache将直接服务所有“/Media_url/”,而无需通过WSGI模块将请求发送到Django。
如果请求从Media_url/ Ticket/ Apache开始,请通过WSGI模块将请求发送到Django。
这就是示例,并根据您的需求 /需求 /案例更改它。 我希望这对任何人试图保护某些Django媒体URL。