我有一个看似非常常见的问题,但我无法找到任何帮助。假设我有一个经过身份验证的用户将私有照片上传到我服务器上的不可浏览文件夹。每个用户在大型文件存储中都有自己的文件夹,例如......
/ FileStore的/ {用户ID} /Photos/my_cute_cat.jpg
文件已上传,我保存了照片的缩略图,如...
/ FileStore的/ {用户ID} /Photos/Thumbs/my_cute_cat_thumb.jpg
该用户想要下载他们的照片。没问题......
我需要在用户仪表板上的普通旧img标签中显示缩略图。 / Thumbs /文件夹未设置为提供静态图像。我不希望/ thumbs /文件夹能够提供静态图像,因为它们只应对授权用户可见。我该怎么办?
答案 0 :(得分:3)
首先,如果静态文件不应该对整个世界可用,那么您的Web服务器不应该提供中的所有目录。在这方面没有别的办法。如果提供了目录,则图像可能会泄漏。
然后提出了如何允许用户访问它的问题。简单的答案是,您需要一个返回图像的授权操作。基本上,这看起来像是:
[Authorize]
public async IActionResult Image(string image)
{
var file = $"/FileStore/{User.Identity.GetUserId()}/Photos/{image}";
if (!File.Exists(file))
return NotFound();
return File(file);
}
现在,显然,我不知道您的“FileStore”,因此这里的确切代码可能需要更改。一般的想法是,您只需查看该文件是否存在于用户的目录下。如果是的话,他们可以拥有它。如果没有,他们就不拥有它。您还应该添加更多安全性,例如将image
param限制为仅图像类型,这样有人就无法尝试提取任何任意文件。他们仍然必须以某种方式设法在那里获得一些异常文件,但最好不要冒险。
退货方法也可能需要改变。现在,我假设服务器的文件系统上有一个文件,所以我只返回一个FileResult
的路径。如果您从Azure,AWS等的某种存储帐户中提取它,那么您将使用HttpClient
发出请求,然后您应该将响应直接流式传输到{{1} }。
答案 1 :(得分:1)
我没有在linux上测试,但是如果你创建一个文件夹,你可以创建一个返回文件的控制器方法。现在,即使您使用的是另一种方法提供的视图,您仍然可以从此剃刀视图中调用此文件方法并显示该图像。
在名为App的控制器中的我从名为Documents:
的文件夹中提供图像<section><div (click)='scrollDown()'>Goto Reports</div></section><div>
在剃刀中(使用一点引导程序):
public IActionResult File(string id)
{
if (String.IsNullOrEmpty(id))
{
return PhysicalFile(Path.Combine(_env.ContentRootPath, "Documents", "Wrong.png"), "image/jpg");
}
return PhysicalFile(Path.Combine(_env.ContentRootPath, "Documents", id), "image/jpg");
}
使用提供文件的方法的位置。
答案 2 :(得分:1)
如果只是一个小拇指钉,请考虑使用嵌入式base64图像,其中包含更多详细信息: How to display Base64 images in HTML?
您可以将base64向下传递给View,方法是将文件编码为base 64格式,如下所示: http://www.devcurry.com/2009/01/convert-string-to-base64-and-base64-to.html
使用此方法或甚至使用FileActionResult通过控制器提供文件具有无法使用CDN来传递缓存内容的巨大缺点。你可以做些什么来帮助这个仍然静态地提供图像,但给他们淫秽长的随机名称,这是不可能的。当有人向您请求图像时,您只需向他们提供不可提交的网址即可。