如果我使用基于令牌的身份验证,我应该如何加载图像
Posted
技术标签:
【中文标题】如果我使用基于令牌的身份验证,我应该如何加载图像【英文标题】:How should I load images if I use token-based authentication 【发布时间】:2016-03-09 21:10:02 【问题描述】:我在域 client-domain.com
上有一个客户端应用程序,在域 server-domain.com
上有一个服务器端应用程序。服务器端有一个 API。客户端应用程序向服务器端应用程序发送 AJAX 请求。我使用基于令牌的身份验证,因此客户端应用程序在每个 AJAX 请求的标头中发送令牌,例如:“Authorization: Bearer some token”。当我需要获取或发布一些数据时,它适用于 AJAX 请求。
但服务器端 API 也保存文件。例如图像。这些文件是私有的,只有经过身份验证的用户才能获取它们。我需要在客户端的<img>
标签中显示这些图像。我无法使用<img src="http://server-domain.com/path/to/image">
获取它们,因为在这种情况下,浏览器不会将授权标头发送到服务器端。
采用的解决方案是什么?客户端应用程序如何从服务器端 API 加载图像?
【问题讨论】:
这里有好的答案***.com/questions/4285042/… Imho,最好的 - 在第二个答案中使用浏览器缓存(我不确定解决方案是跨浏览器) 我想我在你的另一个问题中回答了这个问题:***.com/a/34112350/18044 【参考方案1】:有三种方法可以解决,最好的解决方法是使用签名的网址
-
第一种方法只是创建一个无需身份验证(匿名访问)的路由,并使用签名哈希参数指示资源是否可以加载。
<img src="http://server-domain.com/path/to/image?guid=f6fc84c9f21c24907d6bee6eec38cabab5fa9a7be8c4a7827fe9e56f2">
当服务器收到请求时,如果未达到过期时间,则必须验证 guid,当然,还要检查 guid 是否为有效签名。
这种方法被多个文件/文档服务器使用,例如 Dropbox、S3、CDN 提供商等。
看看一些公司的技术。
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html#private-content-overview-choosing-duration
https://client.cdn77.com/support/knowledgebase/cdn-resource/how-do-i-set-up-signed-urls
第二种方法是通过带有图像 URL 的查询字符串传递令牌。
这种方法不推荐,因为暴露的url很清楚,很多服务器有时会写入和暴露访问的url的公共日志。不好的一点是 JWT 正常暴露,用户可以控制很多功能,进一步加载图像。<img src="http://server-domain.com/path/to/image?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c">
当服务器收到请求时,您必须通过查询字符串验证令牌并响应内容。
第三种方法创建一个经过身份验证的 cookie 来验证对图像的访问。
不推荐使用此方法,因为它不符合 API 模式(通常基于 webapi/token 的身份验证)。当服务器收到请求时,你需要验证 validate cookie 是否有效。
【讨论】:
你能解释一下为什么选项 2 不能防止 XSS 并且大概为什么选项 1 可以吗?在选项 1 中,我们如何生成和验证 guid? 1 和 2 有什么区别? 2 中的令牌与 1 中的 guid 用途不同吗? @gaurav5430,1和2的区别是第一种情况GUID是数据库中的记录,类似自定义方案,第二种是基于JWT(行业标准RFC 7519)的认证方式跨度> @srayner 你是对的,这两种情况具有相同的安全级别。要生成 guid,您必须使用任何技术来制作 UUID 并验证您需要使用自定义解决方案(例如使用 DB)来完成。 @JefersonTenorio 那么,在第一种情况下,任何(经过身份验证/未经身份验证的)用户都可以在 guid 有效时访问资源?有第一种方法的示例实现吗?我查看了链接,但它们似乎非常特定于他们谈论的生态系统。【参考方案2】:根据 Jefferson Tenorio 在下面的回答(选项 1),我对这个完全相同的问题的解决方案是使用图像加密和用户的 JWT 令牌对我的 API 调用的 URL 进行签名,例如path/to/image?token=xxxx
。在 laravel 中,这很容易通过 encrypt($your_object)
和 decrypt($token)
(https://laravel.com/docs/5.7/encryption) 完成,然后我使用提取的令牌来验证用户是否可以访问相关文件。但可能还有许多其他库能够处理这个问题。
如果存在任何安全问题,我会很好奇,但从我的角度来看,JWT 永远不会通过纯文本公开,并且加密依赖于恶意行为者不应访问的密钥,因此它似乎应该相当安全。我唯一真正的抱怨是令牌很长,使用这种方法不适合呈现 URL。
【讨论】:
这感觉就像上面 Jefferson 回答中的选项 2。感觉很容易实现,但正如您所问,是否存在任何安全隐患? 这可能有用。 ***.com/questions/32722952/… @srayner 主要区别在于我没有以纯文本形式公开 JWT 令牌,这是他对选项 2 的问题。相反,我正在加密一个包含 JWT 令牌以及名称的对象有问题的文件作为文件 URL 的令牌,然后可以通过验证 JWT 是否有效以及文件名与所请求的文件匹配来对其进行解密以访问该文件。因此,加密令牌仅对相关文件有用,不能用于访问其他文件。您可以更进一步,并输入用户信息以防止共享以上是关于如果我使用基于令牌的身份验证,我应该如何加载图像的主要内容,如果未能解决你的问题,请参考以下文章