简体   繁体   中英

Download file from Amazon S3 on local machine without letting user know the source of file in codeigniter PHP

1) Below is my code to download a private file from Amazon S3 in codeigniter, $this->S3 has my client information(key/secretkey), when I use below code it saves file on my root directory on server, I want to save it on users local machine's default download location, as I do not know specific end user download location, any help to tackle this??

I have researched whole day, couldn't find a specific solution.

$result1 = $this->S3->getObject([
            'Bucket' => $bucket,
            'Key'    => $keyname,
            'SaveAs' => $keyname
            ]);

Note: I do not want to show the end user that we are downloading files from amazon server, that's why below solution gets failed on firefox

2)

$cmd = $this->S3->getCommand('GetObject', [
        'Bucket' => $bucket,
        'Key'    => $keyname,
        'ResponseContentDisposition' => 'attachment; filename="'.$keyname.'"'
]);
$signed_url = $this->S3->createPresignedRequest($cmd, '+1 minute');
$url=$signed_url->getUri();
header('Location: '.$url);

Screenshot of Firefox save as popup showing source download url

Depending on how much code you want to write, there's many ways to tackle this. The most recent I used was a little over complex because of a lot of security requirements. It was, in a nutshell, like this:

  1. Create a table with the basic data for each uploaded/stored file.

This includes basically all parameters that the upload library outputs after processing a file, plus some additional ones like a user group ID (because each file can be viewed only by a specific user group), a Y/N available flag and a soft-delete date.

  1. Create a downloads controller that will handle all download-related tasks

I created a couple methods within, tasked with verifying that the user was indeed allowed to access that particular file (or redirecting him to an error page if not) The file is on a S3 bucket, mounted on my webserver with s3fs, by the way but that's irrelevant. What you need is agnostic to where the file actually is.

  1. Generate non-obvious download links

Instead of linking to example.com/files/filename.pdf (which would make it trivial to harvest files) my download links point to a specific method in my download controller (downloads/get_file) and passes a non-obvious identifier as a parameter. IIRC I used the encrypted rawname parameter so the links look like

<a href="mysite.com/downloads/get_file/hdhekfnflsufdifnfbs">get hello.pdf here</a>
  1. Find file, stream it to the user

When going to the above link, the get_file method takes the rawname as parameter, finds the file in the table (gets the local path) and outputs it to the browser. This way, the user never sees the real route/parh or even the real file name as stored on disk.

Step 1 put the code in your controller (its working on AWS new image url also)

    $url="http//:projectname/foldername/map.jpg"

    $data = $this->file_get_contents_curl($url);
    $fp = 'map.png';
    $this->load->helper('download');
    force_download($fp,$data);

Step 2 also put the code in your controller

    private function file_get_contents_curl($url) {
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_URL, $url);
          $data = curl_exec($ch);
          curl_close($ch);
          return $data;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM