file download with temporary link using php - php

I am working on a project where the user would be able to buy media files.
after the payment is processed I would like to allow them to download the file.
I guess it is safe to say that I should have a temporary link to the files. one that is linked to the IP of the user and perhaps a timestamp?
the problem is I dont know where to start with that.
First of all. is this the way to do it? if so..how do I proceed using php. ( i guess I dont need the exact script just hints on how to do it although if there is an existing script I would not mind)
thank you.

Since you are going to handle the file in PHP you might aswell use a login to check if the user has purchased the file, other than that the code should look a little like this:
header('Content-Type: application/force-download');
$file = new File(intval($_GET['id']));
$fileLocation = dirname(__FILE__) . "/../../upload/fileArchive/" . $file->id . "." . $file->type;
header('Content-Length:' . filesize($fileLocation));
header("Content-Disposition: inline; filename=\"".$file->name."\"");
$filePointer = fopen($fileLocation,"rb");
fpassthru($filePointer);
Taken from production and tested

I wouldn't tie the temporary link to an IP, it isn't very user-friendly solution.
Store the purchased media in a table for example:
Media id (This refers to an another table where the media details described)
Unique token (This will identificate the purchase)
Client id
Total downloads (Maybe you want to enable the download 5 times)
Token expiry (If you want to limit the access on this)
The download url must contain the unique token and some more data (user's hashed e-mail, etc.) to make the url more unique and more secure.
Sample URL: http://example.com/purchase/nc9o32ocrn8of4nv348/989934ov9344b
First hash holds the purchase itself while second one identifies the user. On successful identifying you can serve the file like Kristoffer said.

header('Content-Type: application/force-download');
$filee = "r.txt";
$fileLocation = dirname(__file__).'/the_sub_folder_for_file/'.$filee;
header('Content-Length:' . filesize($fileLocation));
header("Content-Disposition: inline; filename=\"".$filee."\"");
$filePointer = fopen($fileLocation,"rb");
fpassthru($filePointer);

Related

Php header() User Agent Change

$file_name = $_GET['title'];
$file_url = $_GET['url'] . $file_name;
header('Content-Type: video/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
I'm using this code to download files in my site fetching from another websites.
It works if my url looks like:-
https://www.example.com/video_download.php?title=video.mp4&url=http://googlevideo.com/video/download/223689/289048
(example)
So, it starts downloading by fetching the video file from http://www.googlevideo.com/video/play/221589 to my site.
But my problem is that the file can be accessed if the person uses a PC.
Can I change the User Agent by using header()?
Is it possible?
So if I change the user agent into a PC user agent, so it can be downloaded from a mobile!
I'm sorry, but the User Agent has nothing to do with readfile() function. Readfile() will just throw the raw file input into your browser. Useful for e.g. rendering images through PHP to the client without having to expose the real file name.
Indeed, it is possible to render video to the client with readfile(), but using a HTML5 video tag will dramatically improve performance. This will also provide better mobile support.
Hope this helps you,
You can use stream_compy_to_stream
$video = fopen($file_url);
$file = fopen('videos/' . $title . '.mp4', 'w');
stream_copy_to_stream($video, $file); //copy it to the file
fclose($video);
fclose($file);
I wrote a class for downloading youtube video files. you can find it here.

PHP protecting downloads

I need a method to protect the download URL of a file from being seen by the downloader.
The idea is that the user is given a download link after paying, but to stop them spreading the URL among their friends who haven't paid.
What are some common solutions to this? Possibly changing file name?
(I can do PHP, and mySql this post is for methods really)
If users have an account on your site, stock in your DB if they paid the download. Then give them a link such as download.php where you verify if they paid, and if yes, do a location to the file. Example for a .pdf :
if($userpaid === true) {
$filename = 'congrat-you-paid-it.pdf'; //Name to display
$file = './download/pdf/secretlink.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="'.$filename.'"');
header('Content-Length: ' . filesize($file));
#readfile($file);
exit;
}
One solution could be to use SESSION or a similar temporary storage and generate download URLs at run-time. So clicking on the URL again may not work.
Also, direct access to the files should not be allowed.
Create a token. Store at your end and send with file URL as well. When user clicks the URL match the token and allow the download, then remove token from your storage.
You've to generate new token every time registered user wants to download though.
Use sessions is quick and easy, for better security, what you can do is:
Put the actual file in a separate folder and put a .htaccess in it to
only allow the script to access that file.
Then generate a random unique variable
Then make a temp file with that name and give the link to it to the
client
Finally run a cron job to delete the unnecessary created files.

PHP/MySQL Hide file links

i am using PHP to connect to a MySQL Database and customers can login to my website and it lists rows form a table based on their login etc.
I need to be able to display a link to a file name in the database but i don't want users to be able to see the link to the file.
for example, they can download file 1234.pdf and if they can view the actual link, they might think of going to the same location but doing file 5678.pdf which is only meant for another user to download.
so basically i want to hide the link in a long string or something but i'm not sure where to start - any ideas?
Thanks
EDIT:
lets say Customer A logs in, they can view rows from table1
TABLE1
customer file_link
A 1234.pdf
A 5678.pdf
B 8765.pdf
B 4321.pdf
so, i dont want customer A to be able to view the links for customer B.
i mean, if customer A hovers over a link and can see the main file path they can type this in their web browser and then change the file name (guess it) to something else and download another customers file(s)
if you're planning on not letting others see the file links then you probably wouldn't want search engines to see them as well. A typical way of forbidding users from trying out such stuff is to have a specific page that flushes the file instead of linking directly to the file. E.g.,
Download
then in download.php you could check user permissions and make the browser download the file.
<?php
$file = 'file1234.pdf';
$file_url = 'http://www.test.com/files/' . $file;
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename="' . $file_url . '"');
readfile($file_url);
die();
?>
I think this is what you'll need.

Protect downloads on remote server

I have 2 servers. On Server 1 I have a WordPress website. On Server 2 I have large .zip files that I want members from the WordPress site to be able to download.
How do I authenticate these users so that only people that are members of the website can download files from the second server?
Is it possible to use PHP so that only referrers from my domain have access to the files?
Note: The links to download the files are protected on the wordpress site so that non-logged in users are redirected to a join page. However, current and ex-members would still know the directory where the downloads are and could possibly download the files or share the links.
There are several ways of doing this. The most secure way would be to have some back-end communication between Server 1 & Server 2. But here is an easy alternative:
Server 2 : download.php
<?PHP
$file = $_GET['f'];
$code = $_GET['c'];
$ip = $_SERVER['REMOTE_ADDR'];
if ($code != md5($ip . 'salt')) {
die('authentication denied');
}
if(!file)
{
die('file not found');
}
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile('/files/downloads/' . $file);
?>
Server 1 : Download link
<?PHP
echo 'Download File';
?>
This system works by creating a link that can only be used on the IP it was generated for. So a registered user cannot share the link elsewhere. It's not the most secure thing but it's easy to implement and will work.
Some neat solution may be to use a token system based on current time. You can take current hour of the day and hash it with some salt, and put it in the query string as token. Than php script on second server may check if query-string hash is same, as hash generated for current hour of the day with same salt on server side.
To be sure that user won't hit the hour-switch time you can check for previous hour hash too.
It makes you certain that file url won't be available for more than two hours with guaranteed time of availability of one hour.
On server 1:
<?php
echo 'Link';
?>
On server 2:
<?php
current_hour_hash = md5( date('G').'secret_word' );
previous_hour_number = ( int(date('G')) - 1 ) % 24;
previous_hour_hash = md5( str(previous_hour_number).'secret_word' );
if($_GET['token']!= current_hour_hash and $_GET['token']!= previous_hour_hash){
die();
}else{
... //code sending file here
}

Download prevention like RapidShare.com? hows is it working?

I want to prevent downloading the zip file from my site. Only allowed for some times(at the time of payment). How can it me possible to expire that link or somthing like that to prevent my zip files.
How the rapidshare.com working? we can see the url but not possible to download ??
look at my answer and the comments on this question What is the best method to hide a file on a server? .. this is an idea and may work well for u , if u find it interesting and you agree with it
Edit:
As for how rapidshare works , i think u can hold the time when u want the actual download to happen in session and disable the link button with javascript on the UI , so even if they find the link and they goto it , you can check the time against the session time and redirect them elsewhere.
I am assuming only a registered member can download? You can store the time of payment in a database. Then the download can be accessed through a url like this: http://myhost/download-file.php?file=the-file-name.smthn
When the user goes to this url do all the credential checks like user name and password and the time he has paid. If he is allowed to download fetch the file and output to the browser like so:
$file = file_get_contents('dir-inaccessible-through-web/the-file-name.smthn');
header('Content-disposition: attachment; the-file-name.smthn');
// optionally
$size = strlen($file);
header('Content-length: ' . $size);
echo $file;
Note that the actual file is inaccessible to the web.

Categories