我有以下控制器,连同返回的图像,阻止直接链接:
public class ImageController : Controller
{
[HttpGet]
public ActionResult Details(string id, string file)
{
if (null == Request.UrlReferrer ||
Request.UrlReferrer.Authority != Request.Url.Authority ||
Request.UrlReferrer.AbsolutePath.ToLower() != Url.Action("Photos", "Home", new { id = id }).ToLower())
{
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
// else process and return image
}
}
这样可行,但它有轻微的气味。 MVC-ier会告诉我这件事吗?我最初对ControllerContext
充满希望,但事实并非如此。
以下是我从我的观点中调用此操作的方法:
@foreach (var item in Model.Items)
{
<li>
<img src='@Url.Action("Details", "Image", new { id = Model.Project, file = item.ThumbnailPath })' />
</li>
}
答案 0 :(得分:1)
在您的视图中生成包含id + file + datetime的加密字符串。在你的img src @ Url.Action中传递这个加密的字符串。
在您的Controller中,解密此字符串以获取ID&amp;档案&amp;约会时间。如果日期时间大于15秒,则不要为图像提供服务。如果密钥未成功解密,则不提供图像。
由于加密逻辑是私有的,其他人无法伪造请求,并且由于您在加密密钥中有日期时间,因此您可以在10-15秒内使链接过期,因此其他人无法热链接到您的图像。
希望这是有道理的。
@foreach (var item in Model.Items) {
<li>
<img src='@Url.Action("Details", "Image", new { encryptedString= item.encryptedString})' />
</li> }
public class ImageController : Controller
{
[HttpGet]
public ActionResult Details(string encryptedString)
{
try
{
string[] values = DescryptString(encryptedString);
// values[0] = id
// values[1] = file
// values[2] = datetime
if(dateTime difference < 10 seconds )
return process and return image ;
else // link expired
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
catch(DecodingException e)
{
// forged request
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
}
}