I am using the Storage::url() function for generating download links for files inside the storage directory, i also linked the storage directory to the public directory and everything is working fine.
However now any person can download the files without needing any authentication. What is the proper way to secure all routes starting with /storage/..... without having to re-write the download logic inside my controller?
you must add the download URL as a route on your routes.php file :
Route::get('downloads/{file}','MyController#download')->where('file', '^[^/]+$')->middleware('auth');
of course, don't forget to check if the file exists, after that you can use
$reponse()->download()
to return a download response. the method takes 3 parameters : file path, file name and HTTP response headers.
for more details, check this :
https://laravel.com/docs/5.7/responses#file-downloads
Related
I have developed a small web application that runs a web server in golang.
Each user can login, view the list of their docs (previously uploaded) and click on an item to view an html page that shows some fields of the document plus an tag with a src attribute
The src attribute includes an url like "mydocuments/download/123-456-789.pdf"
On the server side I handle the URL ("mydocuments/download/*") via an http Handler
mymux.HandleFunc(pat.Get("/mydocuments/download/:docname"), DocDownloadHandler)
where:
I check that the user has the rights to view the document in the url
Then I create a fileserver that obviously re-maps the url to the real path of the folder where the files are stored on the filesystem of the server
fileServer := http.StripPrefix("/mydocs/download/",http.FileServer(http.Dir("/the-real-path-to-documents-folder/user-specific-folder/)))
and of course I serve the files
fileServer.ServeHTTP(w, r)
IMPORTANT: the directory where the documents are stored is not the static-files directory I sue for the website but a directory where all files end after being uploaded by users.
My QUESTION
As I am trying to convert the code for it to work also on Google Cloud, I am trying to change the code so that files are stored in a bucket (or, better in "sub-directories" -as they do not properly exist- of a bucket).
How can I modify the code so to map the real document url as available via the cloud storage bucket?
Can I still use the http.FileServer technique above (if so what should I use instead of http.Dir to map the bucket "sub-folder" path where the documents are stored)?
I hope I was enough clear to explain my issue...
I apologise in advance for any unclear point...
Some options are:
Give the user direct access to the resource using a signed URL.
Write code to proxy the request to GCS.
Use http.FS with an fs.FS backed by GCS.
It's possible that a fs.FS for GCS already exists, but you may need to write one.
You can use http.FileSystem since it is an interface and can be implemented however you like.
I have created .bin file download functionality. All my .bin files are stored in the 'storage/app/files' folder. User from view template press on the download button, which appeals to the controller who handles all download functionality (checking if the user is logged in, are file is existing on 'storage/app/files' folder). My question is, does it's safe to store all my important files to this folder? Do I need to write a .htaccess file?
Only your public folder (with index.php) should be accessible, this is the root directory (sometimes the directory is named public_html).
Any directories outside that (like storage/app/vendor etc.) should be unreachable by URL.
"Everything" must go through index.php first if you want to keep control of your files.
So in order to serve assets like storage/app/files/xxx.png you should be using a controller. That code could look something like this:
// SomeController.php
public function showAvatar(Request $request)
{
// Select the `local` disk as defined in `config/filesystems.php`.
$disk = Storage::disk('local');
return response()->file($disk->path('files/xxx.png'));
}
You can then use middleware or other code to provide restrictions to these files.
I have a requirement to send the folder details in the URL for POST method, some thing like this
http:///{directory}/{filename}
I am using Spring API to create the service. Using #PathVariables to two variables in the URI.
Problem : Directory can have "/" slashes in it.
Now how can I create my API, please help me.
POST http://example.com/api/files/path/to/my/file/filename
Stick a controller on /api/files. Scrape the URL starting after /files. Use that to locate the file.
P.S. This has the potential to be a Very Bad Idea. Make sure you secure the controller to only expose those parts of your filesystem you don't mind random internet strangers to be able to operate on.
I'm using GroceryCRUD to act as a front end for a database containing news releases. Secretaries can go in and add/edit/delete news releases in the database easily now. Only qualified users are able to access the application root via an .htaccess password. The problem with this is that GroceryCRUD uploads assets such as photos are uploaded to the directory /www/approot/assets/uploads/ which is password protected since /approot/ is protected.
My ideal solution would be to set an upload directory outside of the application root which is where I'm running into trouble. By default this is how GroceryCRUD handles uploads:
$this->grocery_crud->set_field_upload('photo1','assets/uploads/');
I've tried changing it to something like this:
$this->grocery_crud->set_field_upload('photo1','/public/assets/uploads/');
I was hoping this / would make the path start from the document root instead of the application root, but it throws this error:
PHP Fatal error: Uncaught exception 'Exception' with message 'It
seems that the folder "/Users/myusername/www/approot//public/assets/uploads/"
for the field name "photo1" doesn't exists.
This seems to suggest that CI or GroceryCRUD just takes the second argument in set_upload field and just concatenates it onto the end of the site URL that is defined. Is there any way around this that doesn't involve creating a user login system?
Try using relative path.
$this->grocery_crud->set_field_upload('photo1','../assets/uploads/');
.. -> Go up one directory
I ended up implementing a login system outlined in this tutorial:
http://net.tutsplus.com/tutorials/php/easy-authentication-with-codeigniter/
It was quite simple to set up and suits my needs. I found ways to give access to the directory using httpd.conf directives but I feel like this was a more viable solution since I don't have direct access to server configuration files.
Maybe in the future GroceryCRUD will allow placement of uploads outside the application folder.
I'm using the upload module to write the uploaded file to disk as soon as it arrives in nginx. In addition, I'd like to create 2 subrequests:
POST to a URL containing the uploaded file
POST to another URL without the uploaded file
The second request is easy to do because the upload module has already stripped out the upload. My problem is with the first request: How do I get the uploaded file back into the the subrequest.
A solution for my question has been committed to the echo module.
The module you linked to has the upload_set_form_field directive and a few special variables (listed in that directive), which you can use to pass the file details to the backend as a POST variables. The example given appears to put the upload back in the POST data. Can you adapt your backend script to make that work?