djangomedia-url

how can restrict access to media image URL in django


how can restrict access to media image url , and make it accessible only by access owner user in django ,

here is my class model :

class private_image(models.Model):
    i_user = models.OneToOneField(User, related_name='related_PRF_user', on_delete=models.CASCADE)
    i_image= models.ImageField(upload_to='images', blank=True, null=True )

and my media settings is :

MEDIA_ROOT = os.path.join(BASE_DIR, 'media_root/')
MEDIA_URL = '/media_url/'

for example : i don't want users put the image url like this "http://127.0.0.1:8000/media_url/images/67155_0_AVemgEZ.jpg" in their browsers and open the image , if the request user not same owner user.

i believe, i can make a small function to check access-user and requested URL '/media_url/images/' to get image name , and then get an object from database using image name and then check the owner(i_user) if same access-user .

but how can i tell Django to use this function before service MEDIA_URL requests .

if you have an example , that will be very helpful .

thank you in advance


Solution

  • All requests for media should go throught a specific view.

    myproject/urls.py:

    from myproject.views import media_access
    
    urlpatterns = [
        ...,
        path('media_url/images/<str:path>', media_access, name='media'),
        # or
        # url(r'^media_url/(?P<path>.*)', media_access, name='media'),
    ]
    

    Add the view and check access.

    myproject/views.py:

    from django.http.response import FileResponse
    from django.http import HttpResponseForbidden
    
    def media_access(request, path):    
        access_granted = False
    
        user = request.user
        if user.is_authenticated():
            if user.is_staff:
                # If admin, everything is granted
                access_granted = True
            else:
                # For simple user, only their documents can be accessed
                doc = user.related_PRF_user.i_image  #Customize this...
    
                path = f"images/{path}"
                if path == doc:
                    access_granted = True
    
        if access_granted:
            response = FileResponse(user.related_PRF_user.i_image)
            return response
        else:
            return HttpResponseForbidden('Not authorized to access this media.')
    

    Plz tell me this works or not..