我使用ASP.NET 我需要给用户提供临时链接,以便从服务器下载文件 它应该是一个临时链接(页面),可以在短时间内使用(例如12小时)。如何生成此链接(或带链接的临时网页)?
答案 0 :(得分:8)
这是一个相当完整的例子。
首先使用秘密盐加上到期时间来创建短十六进制字符串的函数:
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);
}
然后生成一个带有一周到期的链接的片段:
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);
如果给出了有效链接,最后是发送文件的下载页面:
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
}
你应该在一些异常处理中包装以捕获错误的请求。
答案 1 :(得分:6)
http://example.com/download/document.pdf?token=<token>
<token>
部分是关键所在。如果您不想涉及数据库,请加密链接创建时间,将其转换为URL安全的Base64表示并为用户提供该URL。在请求时,解密token
并将存储在那里的日期与当前日期和时间进行比较。
或者,你可以有一个单独的DownloadTokens
表,它将所述token
s(可以是GUID)映射到到期日期。
答案 2 :(得分:3)
在查询字符串中为URL添加时间戳:
page.aspx?time=2011-06-22T22:12
根据当前时间检查时间戳。
为了避免用户自己更改时间戳,还要在时间戳上计算一些秘密哈希值,并将其附加到查询字符串:
page.aspx?time=2011-06-22T22:12&timehash=4503285032
作为哈希,您可以执行类似DateTime模数中所有字段的总和的某些素数,或者时间的字符串表示的SHA1和。现在,用户将无法在不知道正确哈希值的情况下更改时间戳。在page.aspx中,根据时间戳的哈希值检查给定的哈希值。
答案 3 :(得分:1)
有一百万种方法可以做到这一点。
我为项目做过一次的方法是生成一个唯一键并使用动态下载脚本来流式传输文件。在生成文件请求时,生成密钥并将其存储在db中,并创建时间和请求的文件。您构建下载脚本的链接并传入密钥。从那里很容易跟踪到期。
答案 4 :(得分:1)
llya
我假设您不需要任何身份验证,安全性不是问题 - 即如果有人获取了URL,他们也可以下载该文件。
我个人会创建一个HttpHandler,然后创建一个可以附加到URL的唯一字符串。
然后在ProcessRequest void测试中编码的param以查看它是否仍然可行(在你指定的时间范围内)如果是这样的话,使用BinaryWrite来呈现文件,如果没有,你可以使用Response.Write呈现一些HTML(“Expired” “)
类似的东西:
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 ); } }
您需要在IIS中设置处理程序,但根据您使用的版本而有所不同。