Clo*_*ans 5 python django amazon-s3 http-headers django-rest-framework
我在DRF中使用令牌身份验证,对于某个API调用,想要重定向到S3(使用类似的URL https://my_bucket.s3.amazonaws.com/my/file/path/my_file.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>
Run Code Online (Sandbox Code Playgroud)
很清楚为什么会发生这种情况 - Authorization带有DRF令牌的标头会随着重定向传播而S3不喜欢它.
在研究并尝试了一百万种方法来摆脱那个标题之后,我放弃了并决定尝试用S3值覆盖标题: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>
Run Code Online (Sandbox Code Playgroud)
如您所见,最终结果是相同的 - 即使我Authorization在响应中覆盖标头,它仍保留原始DRF令牌身份验证值.
# 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)
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是,如何Authorization删除或覆盖DRF响应中的标头?
重定向Authorization标头是客户端的责任(例如浏览器、cURL、HTTP 库/工具包)。
所以基本上,主流浏览器倾向于重定向Authorization标头,这会导致 S3 上的冲突。
我还怀疑您误解了重定向的执行方式:
HTTP 301 or 302向客户端返回一个响应,其中包含新Location标头(请求不会直接通过 DRF“转发”)最后,Authorization当您发出请求时,您不会覆盖任何标头,302因为这是对客户端的响应(可以携带标Authorization头,但毫无用处)。
现在,您有很多解决方案(因此不是开箱即用的......):
HTTP GET( ?token=blah)前两种解决方案可能会在某种程度上破坏 API 的一致性,但在某种程度上是足够公平的。他们需要定制TokenAuthentication或get_authorization_header(来自rest_framework.authorization)。
最后一个是透明的,但可能完全不合适,具体取决于您在 S3 上获取的对象和/或您的托管限制...
目前我能告诉你的就是这些。如你所知,我也遇到过同样的情况。如果有人能提出更好的解决方案,我会很高兴。
| 归档时间: |
|
| 查看次数: |
749 次 |
| 最近记录: |