Create temporary link for download

2019-01-17 13:55发布

I use ASP.NET
I need to give user temporary link for downloading file from server.
It should be a temporary link (page), which is available for a short time (12 hours for example). How can I generate this link (or temporary web page with link)?

5条回答
男人必须洒脱
2楼-- · 2019-01-17 14:03

llya

I'll assume you're not requiring any authentication and security isn't an issue - that is if anyone gets the URL they will also beable to download the file.

Personally I'd create a HttpHandler and then create some unique string that you can append to the URL.

Then within the ProcessRequest void test the encoded param to see if it's still viable (with in your specified time-frame) if so use BinaryWrite to render the File or if not you can render some HTML using Response.Write("Expired")

Something like :

public class TimeHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest ( HttpContext context )
    {

        if( this.my_check_has_expired( this.Context.Request.Params["my_token"] ) )
        {
            // Has Expired 

            context.Response.Write( "URL Has Expired" );
            return;
        }

        // Render the File
        Stream stream = new FileStream( File_Name , FileMode.Open );

        /* read the bytes from the file */
        byte[] aBytes = new byte[(int)oStream.Length];
        stream.Read( aBytes, 0, (int)oStream.Length );
        stream.Close( ); 

        // Set Headers
        context.Response.AddHeader( "Content-Length", aBytes.Length.ToString( ) );
        // ContentType needs to be set also you can force Save As if you require

        // Send the buffer
        context.Response.BinaryWrite( aBytes );                            

    }
}

You need to then setup the Handler in IIS, but that a bit different depending on the version you're using.

查看更多
SAY GOODBYE
3楼-- · 2019-01-17 14:10

Here's a reasonably complete example.

First a function to create a short hex string using a secret salt plus an expiry time:

public static string MakeExpiryHash(DateTime expiry)
{
    const string salt = "some random bytes";
    byte[] bytes = Encoding.UTF8.GetBytes(salt + expiry.ToString("s"));
    using (var sha = System.Security.Cryptography.SHA1.Create())
        return string.Concat(sha.ComputeHash(bytes).Select(b => b.ToString("x2"))).Substring(8);
}

Then a snippet that generates a link with a one week expiry:

DateTime expires = DateTime.Now + TimeSpan.FromDays(7);
string hash = MakeExpiryHash(expires);
string link = string.Format("http://myhost/Download?exp={0}&k={1}", expires.ToString("s"), hash);

Finally the download page for sending a file if a valid link was given:

DateTime expires = DateTime.Parse(Request.Params["exp"]);
string hash = MakeExpiryHash(expires);
if (Request.Params["k"] == hash)
{
    if (expires < DateTime.UtcNow)
    {
        // Link has expired
    }
    else
    {
        string filename = "<Path to file>";
        FileInfo fi = new FileInfo(Server.MapPath(filename));
        Response.ContentType = "application/octet-stream";
        Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
        Response.AddHeader("Content-Length", fi.Length.ToString());
        Response.WriteFile(fi.FullName);
        Response.Flush();
    }
}
else
{
    // Invalid link
}

Which you should certainly wrap in some exception handling to catch mangled requests.

查看更多
smile是对你的礼貌
4楼-- · 2019-01-17 14:17

Append a timestamp to the URL, in the querystring:

page.aspx?time=2011-06-22T22:12

Check the timestamp against the current time.

To avoid the user changing the timestamp by himself, also compute some secret hash over the timestamp, and also append that to the querystring:

page.aspx?time=2011-06-22T22:12&timehash=4503285032

As hash you can do something like the sum of all fields in the DateTime modulo some prime number, or the SHA1 sum of the string representation of the time. Now the user will not be able to change the timestamp without knowing the correct hash. In your page.aspx, you check the given hash against the hash of the timestamp.

查看更多
闹够了就滚
5楼-- · 2019-01-17 14:18

There's a million ways to do it.

The way I did once for a project was to generate a unique key and use a dynamic downloader script to stream the file. when the file request was made the key was generated and stored in db with a creation time and file requested. you build a link to the download script and passed in the key. from there it was easy enough to keep track of expiration.

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-17 14:23
http://example.com/download/document.pdf?token=<token>

The <token> part is key here. If you don't want to involve a database, encrypt link creation time, convert it to URL-safe Base64 representation and give user that URL. When it's requested, decrypt token and compare date stored in there with current date and time.

Alternatively, you can have a separate DownloadTokens table wich will map said tokens (which can be GUIDs) to expiration dates.

查看更多
登录 后发表回答