{"id":18030311,"url":"https://github.com/screamz/securedownloadbundle","last_synced_at":"2026-06-23T03:31:35.993Z","repository":{"id":62541371,"uuid":"47348858","full_name":"ScreamZ/SecureDownloadBundle","owner":"ScreamZ","description":"A resources and documents access key secured bundle for Symfony","archived":false,"fork":false,"pushed_at":"2017-10-05T14:23:00.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-13T02:36:21.190Z","etag":null,"topics":["bundle","file-download","files","php","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ScreamZ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-03T17:38:35.000Z","updated_at":"2018-04-11T13:26:37.000Z","dependencies_parsed_at":"2022-11-02T15:33:05.275Z","dependency_job_id":null,"html_url":"https://github.com/ScreamZ/SecureDownloadBundle","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/ScreamZ/SecureDownloadBundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScreamZ%2FSecureDownloadBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScreamZ%2FSecureDownloadBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScreamZ%2FSecureDownloadBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScreamZ%2FSecureDownloadBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ScreamZ","download_url":"https://codeload.github.com/ScreamZ/SecureDownloadBundle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScreamZ%2FSecureDownloadBundle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271493232,"owners_count":24769117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","file-download","files","php","symfony","symfony-bundle"],"created_at":"2024-10-30T09:13:59.434Z","updated_at":"2026-06-23T03:31:35.987Z","avatar_url":"https://github.com/ScreamZ.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SecureDownloadBundle\n\n[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfe0a24c-3efb-4bfe-a7f5-a3f00ab41bb3/big.png)](https://insight.sensiolabs.com/projects/cfe0a24c-3efb-4bfe-a7f5-a3f00ab41bb3)\n\nThis bundle make it easier and quicker to deploy a secure download document solution, using a Cache engine like Memcached or Redis.\n\nMany cache system are supported thanks to [tedious/TedivmStashBundle!](https://github.com/tedious/TedivmStashBundle).\nAt the moment the default one using service [@stash]( TedivmStashBundle/Service/CacheService.php), but\nfeel free to override my service declaration to use your own.\n\n## Basic usage\n\nIn order to access a secured resource or file you need to pre-authorize this one.\n\nYou either need a file path on the system (full path) or some data you want to save. This can be whole base64 data,\njust some data that will be required to fetch some others data (like through a web-service).\n\nIn order to achieve that, you need to generate an access key that is known by the encoder and the decoder.\nThis will allows you to secure the access to your resource or file, it can be a simple hash or string if the context\ndoesn't depend on it or it can be a salt mixed with a unique identifier of the current logged used, you can also use a cookie to save it or a session variable.\nFeel free to try different approaches.\n\nHere are quick example of common use case:\n\n### I have a path on my API, that I don't want to expose on the frontend\n\n#### TransactionID generation\nThis path must be only accesible to the guy that triggered his generation too. If you share the download link to someone else\nthis guy will not be able to download it.\n\nFor that we need something that identify in a unique manner the user who triggered the transactionID hash. The userID is perfect.\nIf we wanted to allow sharing or the download link we could have used something that is not user-dependant.\n\n```php\npublic function generateHashAction()\n{\n    $secureDownloader = $this-\u003eget('screamz.service.secure_downloader');\n    $currentUser = $this-\u003egetAuthenticationManager()-\u003egetCurrentUser();\n\n    // Provided by the server (client don't know it), use something that identify the current logged user.\n    $accessKey = md5('somecustomhash'.$currentUser-\u003egetId());\n\n    try{\n        // This return a string\n        $transactionID = $secureDownloader-\u003epreAuthorizeDocumentPath('/home/site/www/document.txt', $accessKey);\n    } catch {DownloadRequestException $e){\n        // Do something with errors\n        var_dump($e-\u003egetReasons());\n         \n        // Throw a 400 / 500 HTTP exception\n        throw new HttpException(500);\n    }\n    \n    // Do something...\n    \n    // Return response with the transactionID or render a template with link to download controller...\n}\n```\n\n#### Downloading the file using the given transactionID in a secured way\n```php\npublic function downloadAction($transactionID)\n{\n    $secureDownloader = $this-\u003eget('screamz.service.secure_downloader');\n    $currentUser = $this-\u003egetAuthenticationManager()-\u003egetCurrentUser();\n\n    // Provided by the server (client don't know it), use something that identify the current logged user.\n    $accessKey = md5('somecustomhash'.$currentUser-\u003egetId());\n    \n    try {\n        $binaryResponse = $secureDownloader-\u003egetResourceBinaryFileResponse($transactionID, $accessKey);\n        return $binaryResponse;\n    } catch (DownloadRequestException $e) {\n        // Do something with errors\n        var_dump($e-\u003egetReasons());\n        \n        // Throw a 400 / 500 HTTP exception\n        throw new HttpException(500);\n    }\n}\n```\n\n### I want to save data that will allow me to query a remote API later in order to get something\n\n#### Generate a transactionID\n\n```php\npublic function generateHashAction()\n{\n    $secureDownloader = $this-\u003eget('screamz.service.secure_downloader');\n    $currentUser = $this-\u003egetAuthenticationManager()-\u003egetCurrentUser();\n\n    // Provided by the server (client don't know it), use something that identify the current logged user.\n    $accessKey = md5('somecustomhash'.$currentUser-\u003egetId());\n\n    try{\n        // This return a string\n        $transactionID = $secureDownloader-\u003epreAuthorizeResource(json_encode(['token' =\u003e 'sometoken'], $accessKey);\n    } catch {DownloadRequestException $e){\n        // Do something with errors\n        var_dump($e-\u003egetReasons());\n\n        // Throw a 400 / 500 HTTP exception\n        throw new HttpException(500);\n    }\n\n    // Do something...\n\n    // Return response with the transactionID or render a template with link to download controller...\n}\n```\n\n#### Retrieve the resource after checking authorization\n```php\npublic function downloadAction($transactionID)\n{\n    $secureDownloader = $this-\u003eget('screamz.service.secure_downloader');\n    $currentUser = $this-\u003egetAuthenticationManager()-\u003egetCurrentUser();\n\n    // Provided by the server (client don't know it), use something that identify the current logged user.\n    $accessKey = md5('somecustomhash'.$currentUser-\u003egetId());\n\n    try {\n        $resource = $secureDownloader-\u003egetResource($transactionID, $accessKey);\n    } catch (DownloadRequestException $e){\n        throw $this-\u003ecreateAccessDeniedException('Accès à la ressource non autorisé.');\n    }\n\n    $params = json_decode($resource-\u003egetTransactionSavedData(), true);\n\n    // Call Webservice from here using $params\n}\n```\n## Documentation\n\n* [Error codes](/Resources/doc/error_codes.md)\n* [Default configuration](/Resources/doc/config.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscreamz%2Fsecuredownloadbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscreamz%2Fsecuredownloadbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscreamz%2Fsecuredownloadbundle/lists"}