Php one time use url

When you need to provide a temporary download link that can be used only once, the PHP script in this article can provide the means.

With the download limited to once, there is no longer need to manually monitor activity in order to remove the download file immediately afterward. Instead, the download file can be removed later at your leisure.

Alternatively, the file can be deleted from the server immediately after downloading, instead of renamed.

The download file is in a directory never revealed to the person doing the downloading.

When a download has been completed, the download file on the server is renamed.

If a subsequent download is attempted, the PHP script will be unable to find the requested file because the file was renamed or deleted.

The PHP script allows you to specify the directory where the downloadable files are located.

The script also allows to you to specify the characters used to rename the file. If nothing is specified here, the downloadable file is deleted from the server instead of renamed.

The Single Download PHP Script

Here is the PHP script. Copy it and save it to your hard drive as SingleDownload.php or other appropriate file name.

 $DownloadableFilesDirectory = preg_replace('/^\/*/','/',$DownloadableFilesDirectory); $DownloadableFilesDirectory = preg_replace('/\/*$/','',$DownloadableFilesDirectory); $Directory = $_SERVER['DOCUMENT_ROOT'].$DownloadableFilesDirectory; if( empty($_GET['download']) ) < exit; >if( empty($_GET['savefile']) ) < $_GET['savefile'] = $_GET['download']; >$Dfile = $Directory.'/'.$_GET['download']; $size = filesize($Dfile); if( ! $size ) < echo '

The download file is empty or was not located.

'; exit; > $ctype = 'application/octet-stream'; header('Cache-control: private'); header("Content-Type: $ctype"); header('Content-Disposition: attachment; filename="'.$_GET['savefile'].'"'); header('Content-Transfer-Encoding: binary'); header("Content-Length: $size"); @readfile($Dfile); if( empty($FileRenamePrependCharacters) ) < unlink($Dfile); >else < $pieces = explode('/',$Dfile); $pieces[count($pieces)-1] = $FileRenamePrependCharacters . $pieces[count($pieces)-1]; rename($Dfile,implode('/',$pieces)); >exit; ?>

The PHP script has two places to customize.

  1. Specify the directory containing the downloadable file. Specify the directory as relative to the document root directory. The document root directory is where the domain’s main or index web page file is located. The directory may need 777 permissions so script can rename files in it. Test it first. If the file is not renamed or deleted after being downloaded, then give the directory 777 permissions.
  2. Specify the characters to prepend to the file name when renaming. For example, if you specify «DONE_» and the downloaded file is myfile.pdf, then it will be renamed to DONE_myfile.pdf after it is downloaded. If nothing is specified here, the file on the server will be deleted instead of renamed.
Читайте также:  Programming in python shell

Using the Software

Upload a file to the directory specified in the PHP script.

To download, use the URL of the PHP script appended with «?download=FILENAME».

For example, if the file to download is named myfile.zip, then the URL would be something like this:

With the above link, the browser will suggest the file name to save on the person’s hard drive to be the same as the file name being downloaded.

To suggest a different file name to save on the person’s hard drive, append «&savefile=FILENAME» to the URL. Example:

With the above URL, the file being downloaded is the one named myfile.zip on the server. It is downloaded to be saved as yourfile.zip.

Whenever a file is downloaded, the file on the server is either renamed or deleted depending on your customization.

Was this article helpful to you?
(anonymous form)

Источник

Generating One-Time Use URLs

A one-time URL is a specially crafted address that is valid for one use only. It’s usually provided to a user to gain privileged access to a file for a limited time or as part of a particular activity, such as user account validation. In this article I’ll show how to generate, implement, and expire one-time URLs.

Creating a URL

Let’s say we’ve been tasked with writing a user management component, and the project creates a record for a new user account in the database. After signing up, the user receives a confirmation email which provides a one-time URL to activate her account. We can make this URL one-time by including a tracked token parameter, which means the URL would look like this:

http://example.com/activate?token=ee97780. 

Not surprisingly, tracking the one-time URL is done by storing information in a database table. So, let’s start with the table definition:

CREATE TABLE pending_users ( token CHAR(40) NOT NULL, username VARCHAR(45) NOT NULL, tstamp INTEGER UNSIGNED NOT NULL, PRIMARY KEY(token) );

The table stores the relevant username, a unique token, and a timestamp. I’ll be showing how to generate the token using the sha1() function, which returns a 40-character string, hence the capacity of the token field as 40. The tstamp field is an unsigned integer field used to store a timestamp indicating when the token was generated and can be used if we want to implement a mechanism by which the token expires after a certain amount of time.

Читайте также:  Fake user agent python requests

There are many ways to generate a token, but here I’ll simply use the uniqid() and sha1() functions. Regardless of how you choose to generate your tokens, you’ll want them to be unpredictable (random) and a low chance of duplication (collision).

uniqid() accepts a string and returns a unique identifier based on the string and the current time in microseconds. The function also accepts an optional Boolean argument to add additional entropy to make the result more unique. The sha1() function calculates the hash of the given string using the US Secure Hash Algorithm 1.

Once the functions execute, we’ve got a unique 40-character string which we can use as our token to create the one-time URL. We’ll want to record the token along with the username and timestamp in the database so we can reference it later.

prepare( "INSERT INTO pending_users (username, token, tstamp) VALUES (?, ?, ?)" ); $query->execute( array( $username, $token, $_SERVER["REQUEST_TIME"] ) );

Obviously we want to store the token, but we also store the username to remember which user to set active, and a timestamp. In a real world application you’d probably store the user ID and reference a user record in a separate user table, but I’m using the username string for example’s sake.

With the information safely placed in the database, we can now construct our one-time URL which points to a script that receives the token and processes it accordingly.

The URL can be disseminated to the user either by email or some other means.

Consuming a URL

We need a script to activate the account once the user follows the link. Indeed, it’s the processing script that works that enforces the one-time use of the URL. What this means is the script will need to glean the token from the calling URL and do a quick check against the data stored in the database table. If it’s a valid token, we can perform whatever action we want, in this case setting the user active and expiring the token.

$/i', $_GET["token"])) < $token = $_GET["token"]; >else < throw new Exception("Valid token not provided."); >// verify token $query = $db->prepare("SELECT username, tstamp FROM pending_users WHERE token = ?"); $query->execute(array($token)); $row = $query->fetch(PDO::FETCH_ASSOC); $query->closeCursor(); if ($row) < extract($row); >else < throw new Exception("Valid token not provided."); >// do one-time action here, like activating a user account // . // delete token so it can't be used again $query = $db->prepare( "DELETE FROM pending_users WHERE username = ? AND token = ? AND tstamp = ?", ); $query->execute( array( $username, $token, $tstamp ) );

Going further, we could enforce a 24-hour TTL (time to live) for the URL buy checking the timestamp stored in the table alongside the token.

 $delta) < throw new Exception("Token has expired."); >// do one-time action here, like activating a user account // . 

Working within the realm of Unix timestamps, the expiration date would be expressed as an offset in seconds. If the URL is only supposed to be valid for 24 hours, we have a window of 86,400 seconds. Determining if the link has expired then becomes a simple matter of comparing the current time with the original timestamp and see if the difference between them is less than the expiration delta. If the difference is greater than the delta, then the link should be expired. If the difference is less than or equal to the delta, the link is still “fresh.”

Читайте также:  Html form action get value

Conclusion

There are several applications for one-time use URLs. The example in this article was a scenario of sending a user a verification link to activate an account. You could also use one-time use URLs to provide confirmation for other activities, give time-sensitive access to information, or to create timed user accounts which expire after a certain time.

As a matter of general house keeping you could write a secondary script to keep expired tokens from accumulating in the database if a user never follows them. The script could be run periodically by an administrator, or preferably set up as a scheduled task or cron job and run automatically.

It would also be wise to take this functionality and wrap it up into a reusable component as you implemented it in your application. It’s trivial to do, and so I’ll leave that as an exercise to the reader.

Share This Article

Timothy Boronczyk is a native of Syracuse, New York, where he lives with no wife and no cats. He has a degree in Software Application Programming, is a Zend Certified Engineer, and a Certified Scrum Master. By day, Timothy works as a developer at ShoreGroup, Inc. By night, he freelances as a writer and editor. Timothy enjoys spending what little spare time he has left visiting friends, dabbling with Esperanto, and sleeping with his feet off the end of his bed.

Источник

Оцените статью