【问题标题】:Disable direct access to images禁用直接访问图像
【发布时间】:2012-02-01 03:43:23
【问题描述】:

我正在制作一个小小的家庭相册,打算以后可能会打开给其他人存储图像。

我将图像上传到 ~\images\,然后调整它们 3 次(普通视图...缩略图和小版本)并将它们移动到 ~\images\thumbs、~\images\normal、~\images\ tiny 然后将原件移动到 ~\images\original。

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

我不希望他们可以使用它。

那么,有没有办法将 asp:Image 控件的 ImageUrl 更改为从不可访问的文件夹中读取?这会对性能造成影响吗?我正在考虑类似(不确定是否可能)将图像读入 Steam,并以某种方式设置 ImageUrl 或其他任何东西,以从流中读取?

希望您能提供帮助。

【问题讨论】:

    标签: c# asp.net imaging


    【解决方案1】:

    答案是肯定的。您可以使用特殊格式的 img src 将图像直接嵌入到页面中。

    您可以使用以下格式而不是 URL:

    <img src="data:image/png;base64,..." />
    

    其中 data 指定图像的 mime 类型,base64 之后的 ... 是图像的 base64 编码内容。

    此行为由this 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));
        }
    

    【讨论】:

    • 谢谢 - 我还是迷路了。我还不需要指定图片的url吗?
    • 很抱歉正在处理一个示例,但被一个愚蠢的错误挂断了。我已经更新了答案,但它是 img src,而不是 href(一次处理太多事情)。
    • 这很难被缓存。
    • @CodeCaster:问题中没有将可缓存性作为要求。
    • 对两者都表示肯定:因为图像必须转换为字符串,所以需要处理和传递更多数据。在正常情况下,在使用缓存的情况下,您会看到更大的影响,但由于无论如何都必须检索和发送文件,因此影响不大。您可以使用 fiddler (www.fiddler2.com) 轻松地使用或不使用此解决方案执行一些本地测试,这将显示页面加载所需的时间。
    【解决方案2】:

    我是否可以建议考虑以下内容:

    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
            }
    
        }
    }
    

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

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

    【讨论】:

    • 难道用户不能将mysite.com/images/user/1234/image.jpg 放入浏览器吗?
    • 他们可以,但是如果正确的用户没有登录,那么服务器将简单地返回一个未找到文件的错误,因此拒绝访问不属于他们的图像,即使他们知道在哪里存储它们的服务器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    相关资源
    最近更新 更多