【问题标题】:How to get safe url for image in Flask?如何在 Flask 中获取图像的安全 URL?
【发布时间】:2018-09-25 10:24:58
【问题描述】:

我已将所有图像存储在文件夹 \uploads 中。我已将文件名+扩展名存储在数据库中。每张图片都有名称 PHOTO_ID.jpeg。我有一些关于项目的查询,以及我通过其 ID 连接照片的那些项目。我想发送类似这样的 JSON 响应,其中包含图像的 url。

通缉回复: json:{name: 'somename' url: 'imageURL'}

所以问题是如何获取只能从一个用户访问的 URL。我不希望任何人能够猜测其他图像的 url。 我在 FLASK 中找到了一些方法,但它们需要绑定到某个端点。我不想要显式端点来检索图像的 url。 到目前为止我发现的这些方法:

send_from_directory(DIRECTORY,FILENAME)
url_for(endpoint, filename=filename)
send_file(FILEPATH,'image/' + extension, as_attachment=True)

我想要像 retrieve_url(FILEPATH) 这样简单的东西,它只会为一个用户返回 url 和安全方法。

感谢您的帮助。

【问题讨论】:

  • 将image表中的图片绑定到user表中的用户,只有用户登录才能查询图片。

标签: python python-3.x image flask flask-sqlalchemy


【解决方案1】:

我看到了几种方法

1) 不要使用可预测的文件名,而是使用一些长的随机字符串保存文件并将其链接到数据库中的原始文件名

2) 为静态图片制作自定义路由,并且仅在您验证用户有权访问时发送图片:

@app.route('/send_file/<path:filename>')
def send_file(filename):
    image = Photo.query.filter_by(user_id=session['user_id'], filename=filename).first()
    if  image:
        return send_from_directory('image_folder', filename)
    else:
        return 'not allowed/found'

3 将图像作为 JSON 中的二进制数据发送(更多数据 + 不优雅),请参阅 here

【讨论】:

  • 1) 我绝对可以做到。看起来很安全,有人猜到这个数字的可能性很小。也许我可以使用一些哈希。 2)我不想创建新路线我想在其他方法中调用这个方法。我已经声明了一些端点,并且在该类中我有方法,并且一个获取我想要与图像绑定的数据。但是它给了我错误,因为它需要声明新路线。所以这就是我不想使用它的原因 3)如果有 50 张图片,它的加载速度会很慢。
  • 但是您需要另一条路线来确保只有授权用户才能看到它。我认为自定义路线是唯一的好方法。使用 Aniruddh 的 sn-p 并从那里开始。只需将 URL 放入 json 中,就像描述的那样,然后让您的 download_image 路由从那里获取它。如果您输入用户无权访问的图片中的 ID,他仍然可以看到文件名,但无法下载图片。
  • 但是这样我需要在图像上明确发送请求还是我错了?我已经用令牌保护了端点,但我想创建多个 url,因为我获取了 5O 个项目并且每个项目都有图像。
  • 是的,但是当您向用户发送图像 url 时总是这样做,无论您是否检查它是否被允许。然后用户浏览器再次向服务器请求图像。就像这样 1) 用户发送请求 2) 服务器发送带有图片 url 的 json 3) 用户发送图片请求 4) 服务器发送图片数据
  • Aaah 我明白了,所以不可能像这样在一个 json 中发送 50 个 url:data:[{url: 'url1'},{url: 'url2}] ...
【解决方案2】:

如果您有基于会话的用户管理系统,请创建一个身份验证令牌(任何随机字符串/使用 bcrypt 根据某些会话信息生成加密令牌)将其存储在您的数据库/会话中。

对于您的图像,请执行以下操作:

@app.route('/downloads/<auth_token>/<filename>')
def downloads(auth_token, filename):
    if session['auth_token'] == str(auth_token):
        return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
    return 'You are not allowed to view this page'

加密的会话令牌对于该特定会话的特定用户有效。如果 auth_token 不匹配,则无法通过该 url 访问该文件。

【讨论】:

  • 但我不想创建新路线,我想在其他方法中调用此方法。我已经声明了一些端点,并且在该类中我有方法,并且一个获取我想要与图像绑定的数据。但是它给了我错误,因为它需要声明新路线。所以这就是我不想使用它的原因。
猜你喜欢
  • 2012-12-11
  • 1970-01-01
  • 2012-11-22
  • 2015-12-26
  • 2022-06-20
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 2015-08-27
相关资源
最近更新 更多