2

I have a little problem with my Symfony installation. In my app the user can upload images to the server and the images are stored in /web/uploads/images. I would like that the image be only visible for logged users into the app.

I have tried to modify the security configuration but I don't find the proper configuration to solve the problem. Any idea??

Thanks :)

rdiaz82
  • 996
  • 12
  • 31
  • 1
    I answered similar question before. Take a look here - http://stackoverflow.com/questions/18880785/symfony2-store-uploaded-file-non-rootweb/18881325 – dmnptr Apr 23 '14 at 19:18

3 Answers3

4

Firstly thank you very much for take your time to answer :) I think that both solutions are valid. In my particular case I have implemented the solution proposed by @Patrick.

Coming soon I will need the private images accessible from a mobile app through and url, so for that reason I have implemented a controller instead a twig extension, the controller's code is following:

<?php

namespace Company\Bundle\nameBundle\Controller;

use Symfony\Component\HttpFoundation\Response,
Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DashPrivateImageController extends Controller
{
    public function getImageAction($imagetype, $imagename) {

        $securityContext = $this->container->get('security.context');

        if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {

            if ($imagetype == 1) 
                $path = $this->get('kernel')->getRootDir() . "/../private/documentFolder1/" . $imagename;
            else 
                $path = $this->get('kernel')->getRootDir() . "/../private/documentFolder2/" . $imagename;

            $file = file_get_contents($path);
            $headers = array('Content-Type' => 'image/jpeg', 
                       'Content-Disposition' => 'inline; filename="'.$imagename.'"');
            return new Response($file, 200, $headers);
        } else 
            return new Response("not found", 404);
    }
}
?>

Thanks!!

rdiaz82
  • 996
  • 12
  • 31
2

Images should reside outside /web directory, otherwise visitors of website will always be able to download them. You can create for example /private directory and upload all images there.

For displaying images to users you should create a Twig extension, which will contain something like this (but not the same): How can I allow a user to download a file which is stored outside of the webroot?

After creating the extension you should be able to use something like this in your views:

{{ image_private(image.name) }}

I haven't found a bundle for this so in case that you create some good solution it might be useful if you created a bundle from it and publish it at knpbundles website.

Community
  • 1
  • 1
2

First, move the uploaded images out of the web root.

It will be much harder to hide a folder in an otherwise publicly accessible web directory than just streaming the file to the user from a non-public location.

Second, create a new route or controller that will validate the user's access to an uploaded image and if the credentials match, stream the file from the non-public folder directly from the controller action and do not return any template.

Patrick
  • 3,142
  • 4
  • 31
  • 46
  • What if a user wants to see images inside in for example `ArticleController`, `GalleryController` etc.? That would mean to have inside each `Controller` an `action` for displaying images. Solving it with `Twig extension` is way more elegant solution. –  Apr 23 '14 at 19:55
  • A `Twig extension` doesn't handle the access control, that's what I was aiming at. It would probably be best to create a image auth service that can be called from any controller and use a Twig template to display the image – Patrick May 02 '14 at 18:48