禁止直接访问图片

10

我正在制作一本小家庭相册,可能会开放给其他人存储图片。

我将图像上传到 ~\images\,然后将它们调整大小三次(正常视图...缩略图和微小版本),并将它们移动到 ~\images\thumbs、~\images\normal、~\images\tiny,然后将原始图像移动到 ~\images\original。

如果用户知道文件名,他们可以直接访问http://mysite.com/images/normal/filename.jpg以进行直接访问。

我不希望这对他们可用。

那么,有没有一种方法可以更改 asp:Image 控件的 ImageUrl,以从不可访问的文件夹中读取?这会影响性能吗?我在想的是(不确定是否可行)将图像读入一个流中,并以某种方式设置 ImageUrl 或任何其他内容,以从流中读取?

希望你能帮忙。

2个回答

13
答案是肯定的。您可以使用特殊格式的img src将图像直接嵌入页面中。不需要使用URL,而是使用以下格式:
<img src="data:image/png;base64,..." />

其中data指定了图像的MIME类型,而base64后面的内容则是图像的base64编码。

此行为在此RFC中定义。

以下是一个示例:

在HTML中:

<img id="MyPicture" runat="server" border="0" />

在代码后台:

    protected void Page_Load(object sender, EventArgs e)
    {
        MyPicture.Src = @"data:image/gif;base64," + EncodeFile(Server.MapPath(@"/images/test.gif"));
    }

    private string EncodeFile(string fileName)
    {
        return Convert.ToBase64String(File.ReadAllBytes(fileName));
    }

这几乎不可能被缓存。 - CodeCaster
1
@CodeCaster:在问题中没有指明需要缓存性。 - competent_tech
谢谢 - 我现在正在尝试。由于有编辑图像的选项,我不想使用缓存,并且我发现我必须强制刷新才能看到更改。 - Craig
这会增加页面加载时间还是增加服务器CPU使用率? - Craig
1
对于这两个问题,我的回答是“有条件的肯定”。因为图像必须转换为字符串,所以需要处理和传递更多的数据。在正常情况下,如果使用缓存,影响会更大,但由于文件必须被检索和发送,所以只会有一些中等程度的影响。您可以使用 Fiddler(www.fiddler2.com)轻松地进行一些本地测试,比较使用或不使用此解决方案时页面加载所需的时间。 - competent_tech
显示剩余6条评论

0

我可以建议考虑类似以下的方案:

  1. 将图片保存到一个文件夹中,例如 "siteroot/images/userid/"。
  2. 在成功登录后设置会话变量,以便其他页面知道当前用户已登录。 Session["user"] = youruser; 在您的会话变量中存储的对象中,包括从数据库中提取的有效youruser.userID。
  3. 在站点根目录的 Global.asax 文件中添加类似以下的内容:

(未经测试的代码)

void Begin_Request(object sender, EventArgs e)
{
    //Protect /images/ folder for all requests
    if (Request.FilePath.Contains("images"))
    {
        YourUser user = Session["user"];

        if(user == null) {
            Server.Transfer("404.aspx"); //Folder not public
        }

        if (!Request.FilePath.Contains("images/" + user.userID.toString())){
            Server.Transfer("404.aspx"); //This is not current user's image folder
        }

    }
}

这将有效地拒绝除了各自“图像”文件夹的正确用户之外的所有人访问,即使他们找出了图像文件的直接路径。

如果有人有任何改进此方法的方法,请随时评论,因为我很快将在网站上实施此想法,并且欢迎第二意见。


用户不能在浏览器中输入http://www.mysite.com/images/user/1234/image.jpg吗? - Craig
他们可能会尝试访问图片,但如果正确的用户未登录,则服务器将只返回文件未找到错误,从而拒绝访问不属于他们的图片,即使他们找出了在服务器上存储的位置。 - ToddBFisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接