Prevent direct access to uploaded files only for unauthorized users - Symfony
I followed these steps to achieve this requirement.
- Created a function and added its route in firewall, so anonymous users cannot go to that path.
- Created a route to set its path.
- Got media id in the function and did the functionality to return the file.
- Called the function by its path with parameter
mediaId
instead of calling direct media in twig.
Here is the code.
security.yml
- { path: ^/user(.*), roles: ROLE_DASHBOARD_USER }
routing.yml
cms_direct_access_uploaded_files:path: /user/image-return/{fileId}defaults: { _controller: CMSFrontUserBundle:Dashboard:DirectAccessUploadedMedia }
Controller
public function DirectAccessUploadedMediaAction(Request $request,$fileId = null){ $user = $this->getUser(); if(!empty($user)){ $DM = $this->getDoctrineManager(); $media = $DM->getRepository('ApplicationSonataMediaBundle:Media')->find($fileId); if(!empty($media)) { $provider = $this->container->get( $media->getProviderName() ); $format = $provider->getFormatName( $media, 'reference' ); $url = $provider->generatePublicUrl( $media, $format ); $ext = pathinfo($url, PATHINFO_EXTENSION); $returnFile = $_SERVER['DOCUMENT_ROOT'] .'/web'. $url; if (file_exists($returnFile)) { if($ext == 'pdf'){ header("Content-Type: application/pdf"); }else{ header("Content-Type: image/jpeg"); } header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($returnFile)); readfile($returnFile); exit; } }else{ throw $this->createAccessDeniedException('Forbidden!'); } }else{ throw $this->createAccessDeniedException('Forbidden!'); }}
Twig
{{ url('homepage') }}user/image-return/{{ req.media.id }}