Ajax 如果使用基于令牌的身份验证,应如何加载图像

Ajax 如果使用基于令牌的身份验证,应如何加载图像,ajax,api,authentication,Ajax,Api,Authentication,我在域client domain.com上有一个客户端应用程序,在域server domain.com上有一个服务器端应用程序。服务器端有一个API。客户端应用程序向服务器端应用程序发送AJAX请求。我使用基于令牌的身份验证,因此客户端应用程序在每个AJAX请求的头中发送令牌,例如:“Authorization:Bearer{some token}”。当我需要获取或发布一些数据时,它可以很好地处理AJAX请求 但是服务器端API也保存文件。例如图像。这些文件是私有的,只有经过身份验证的用户才能获

我在域
client domain.com
上有一个客户端应用程序,在域
server domain.com
上有一个服务器端应用程序。服务器端有一个API。客户端应用程序向服务器端应用程序发送AJAX请求。我使用基于令牌的身份验证,因此客户端应用程序在每个AJAX请求的头中发送令牌,例如:“Authorization:Bearer{some token}”。当我需要获取或发布一些数据时,它可以很好地处理AJAX请求

但是服务器端API也保存文件。例如图像。这些文件是私有的,只有经过身份验证的用户才能获取它们。我需要在客户端的
中显示这些图像,因为在这种情况下,浏览器不会将授权头发送到服务器端


采用的解决方案是什么?客户端应用程序如何从服务器端API加载图像?

有三种方法可以解决此问题,解决此问题的最佳方法是使用签名URL


  • 第一种方法只是创建一个没有身份验证(匿名访问)的路由,该路由带有一个签名散列参数,该参数指示是否可以加载资源
  • 
    
    当服务器收到请求时,如果未达到过期时间,则必须验证guid,当然,还要检查guid是否为有效签名

    这种方法被Dropbox、S3、CDN提供者等多个文件/文档服务器使用

    看看一些公司的技术


  • 第二个方法通过带有图像URL的querystring传递令牌

    • 不建议使用此方法,因为它会清楚地公开url,而且许多服务器有时会写入并公开所访问url的公共日志。糟糕的是,JWT正常曝光,用户可以进一步控制图像加载的许多功能
  • 
    
    当服务器收到请求时,您必须通过查询字符串验证令牌,并使用内容进行响应


  • 第三种方法创建一个经过身份验证的cookie来验证对图像的访问

    • 不建议使用此方法,因为它不符合API模式(通常是基于webapi/令牌的身份验证)

  • 当服务器收到请求时,您需要验证验证cookie是否有效。

    根据Jeferson Tenorio下面的回答(选项1),我基本上解决了这个完全相同的问题,我的解决方案是使用图像加密和用户的JWT令牌(例如,
    path/to/image?token=xxxx)为我的API调用的URL签名。在laravel中,使用
    encrypt($your_object)
    decrypt($token)
    ()可以轻松实现这一点,然后我使用提取的token验证用户是否有权访问相关文件。但可能还有许多其他库能够处理这个问题


    我很好奇是否存在任何安全问题,但从我的角度来看,JWT从未通过纯文本公开,加密依赖于恶意参与者不应该访问的密钥,因此它似乎应该相当安全。我唯一真正的抱怨是,使用这种方法的令牌很长,这不利于呈现URL。

    这里的回答很好,第二个答案中最好使用浏览器缓存(我不确定解决方案是跨浏览器)我想我在你的另一个问题中回答了这个问题:你能解释为什么选项2不保护XSS,大概为什么选项1保护XSS吗?在选项1中,我们如何生成和验证guid?1和2之间的区别是什么?2中的令牌不与1中的guid具有相同的用途吗?@gaurav5430,1和2之间的区别在于第一种情况guid是数据库中的记录,就像自定义解决方案一样,第二种情况基于JWT(行业标准RFC 7519)身份验证method@srayner你说得对,这两种情况都有相同的安全级别。要生成guid,您必须使用任何技术生成UUID并进行验证,您需要使用自定义解决方案(例如使用DB)。@JefersonTenorio那么,在第一种情况下,任何(经过身份验证/未经身份验证的)用户都可以在guid有效时访问资源?有没有第一种方法的示例实现?我查看了链接,但它们似乎非常特定于他们所谈论的生态系统。这感觉就像上面杰弗森回答的选项2。这感觉很容易实现,但正如您所问的,是否存在任何安全隐患?这可能很有用@srayner的主要区别在于我没有以纯文本形式公开JWT令牌,这是他在选项2中遇到的问题。相反,我加密了一个对象,该对象包含JWT令牌以及相关文件的名称作为文件URL的令牌,然后可以通过验证JWT是否有效以及文件名是否与所请求的文件匹配来解密该文件以访问该文件。因此,加密令牌仅对相关文件有用,不能用于访问其他文件。你可以更进一步,把用户信息也放进去,以防止共享
    <img src="http://server-domain.com/path/to/image?guid=f6fc84c9f21c24907d6bee6eec38cabab5fa9a7be8c4a7827fe9e56f2">
    
    <img src="http://server-domain.com/path/to/image?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c">