我使用ASP.NET我需要给用户临时链接,以便从服务器下载文件。它应该是一个临时链接(页面),可以在短时间内(例如12小时)使用。如何生成此链接(或带有链接的临时网页)?
这是一个相当完整的示例。
[第一个使用秘密盐加上有效期限来创建短十六进制字符串的函数:
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
}
您当然应该包装一些异常处理以捕获损坏的请求。
http://example.com/download/document.pdf?token=<token>
<token>
部分是关键。如果您不想涉及数据库,请加密链接创建时间,将其转换为URL安全的Base64表示形式,然后为用户提供该URL。根据要求,解密token
并将其中存储的日期与当前日期和时间进行比较。
或者,您可以有一个单独的DownloadTokens
表,该表将把所述token
(可以是GUID)映射到到期日期。
将时间戳添加到URL,在查询字符串中:
page.aspx?time=2011-06-22T22:12
根据当前时间检查时间戳。
[为了避免用户自己更改时间戳,还要在时间戳上计算一些秘密哈希,并将其附加到查询字符串中:
page.aspx?time=2011-06-22T22:12&timehash=4503285032
作为哈希,您可以执行一些操作,例如对DateTime中所有字段的总和以模数进行模运算,或者对时间的字符串表示形式进行SHA1和。现在,用户将无法在不知道正确哈希值的情况下更改时间戳。在page.aspx中,对照时间戳的哈希值检查给定的哈希值。
有百万种方法可以做到。
我曾经为项目做过的方法是生成一个唯一的密钥并使用动态下载脚本来流式传输文件。发出文件请求时,将生成密钥并将其与创建时间和请求的文件一起存储在db中。您将建立一个指向下载脚本的链接并传递了密钥。从那里开始跟踪到期很容易。
llya
我会假设您不需要任何身份验证,安全性也不是问题-也就是说,如果有人获得了URL,他们也可以下载文件。
我个人将创建一个HttpHandler,然后创建一些可以附加到URL的唯一字符串。
然后在ProcessRequest中无效,对编码的参数进行测试,以查看它是否仍然可行(在指定的时间范围内),如果可以,请使用BinaryWrite呈现文件;否则,可以使用Response.Write(“ Expired” )
类似:
公共类TimeHandler:IHttpHandler,IRequiresSessionState{公共无效的ProcessRequest(HttpContext上下文){if(this.my_check_has_expired(this.Context.Request.Params [“ my_token”])){// 已过期context.Response.Write(“ URL已过期”);返回;}//渲染文件流stream =新的FileStream(File_Name,FileMode.Open);/ *从文件中读取字节* /byte [] aBytes =新的byte [(int)oStream.Length];stream.Read(aBytes,0,(int)oStream.Length);stream.Close();//设置标题context.Response.AddHeader(“ Content-Length”,aBytes.Length.ToString());//必须设置ContentType,如果需要,您也可以强制另存为//发送缓冲区context.Response.BinaryWrite(aBytes);}}
然后您需要在IIS中设置处理程序,但是根据您使用的版本而有所不同。
我认为本文可能很有用,并且其中描述的概念可以翻译成您喜欢的语言: