我在 DRF 中使用 token 身份验证,对于某个 API 调用,我想重定向到 S3(使用像 https://my_bucket.s3.amazonaws.com/my/file/path/my_file 这样的 URL .jpg?Signature=MY_AWS_SIGNATURE&AWSAccessKeyId=MY_AWS_ACCESS_KEY_ID
)。但是,我从 AWS 收到以下错误:
<Error>
<Code>InvalidArgument</Code>
<Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>Token a3f61c10592272399099882eb178bd4b755af5bf</ArgumentValue>
<RequestId>E4038228DD1E6330</RequestId>
<HostId>9c2xX59cugrR0CHjxQJR8IBE4MXBbNMX+wX2JdPJEuerkAftc32rufotM7COKLIavakByuRUXOo=</HostId>
</Error>
很明显为什么会发生这种情况——带有 DRF token 的 Authorization
header 随重定向一起传播,而 S3 不喜欢它。
在研究并尝试了一百万种方法来摆脱该 header 之后,我放弃并决定尝试使用 S3 值覆盖 header :AWS MY_AWS_SIGNATURE:MY_AWS_ACCESS_KEY_ID
,之后我得到一个不同的错误:
<Error>
<Code>InvalidArgument</Code>
<Message>Unsupported Authorization Type</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>Token a3f61c10592272399099882eb178bd4b755af5bf</ArgumentValue>
<RequestId>94D5ADA28C6A5BFB</RequestId>
<HostId>1YznL6UC3V0+nCvilsriHDAnP2/h3MoDlIJ/L+0V6w7nbHbf2bSxoQflujGmQ5PrUZpNiH7GywI=</HostId>
</Error>
如您所见,最终结果是相同的——即使我在响应中覆盖了 Authorization
header ,它仍然保留原始 DRF token 身份验证值。
# relevant portion of my response construction
headers = {'Location': 'https://my_bucket.s3.amazonaws.com/my/file/path/my_file.jpg',
'Authorization': 'AWS %s:%s' % (params['AWSAccessKeyId'], params['Signature'])}
return Response(status=status.HTTP_302_FOUND, headers=headers)
所以,我的问题是,如何删除或覆盖 DRF 响应中的 Authorization
header ?
最佳答案
重定向 Authorization
header 是客户端的责任(例如浏览器、cURL、HTTP 库/工具包)。
所以基本上,主流浏览器倾向于重定向 Authorization
header ,这会导致 S3 上的冲突。
此外,我怀疑您误解了重定向的执行方式:
- 当 DRF 发出重定向时,它会向客户端返回一个
HTTP 301 或 302
响应,其中包含新的Location
header (请求不是直接通过“转发” DRF) - 然后,客户端请求这个新的 URI
最后,当您发出 302
时,您没有覆盖任何 Authorization
header ,因为这是对客户端的响应(可以携带Authorization
header ,但这没用)。
现在,您有一堆解决方案(因此不是现成的......):
- 通过不同的 header 传递您的 token 以避免冲突(例如 X-Token)
- 通过
HTTP GET
参数传递您的 token (?token=blah
) - 使用您的 DRF View 代理 S3 对象(然后不重定向)
前两个解决方案可能会以某种方式破坏 API 的一致性,但在某些方面是足够公平的。他们需要自定义 TokenAuthentication
或 get_authorization_header
(来自 rest_framework.authorization
)。
最后一个是透明的,但可能完全不合适,具体取决于您在 S3 上获取的对象和/或您的托管限制...
这就是我现在能告诉你的全部。如您所知,I've been stuck with the same situation too .如果有人能提出更好的解决方案,我将非常高兴。
关于python - Django 休息框架 : redirect to Amazon S3 fails when using Token Authentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33714122/