AmazonS3署名済みURLにPUTリクエストを送信しようとしています。 PUTリクエストが1つしかなくても、リクエストが2回呼び出されるようです。最初のリクエストは200 OK
を返し、2番目のリクエストは400 Bad Request
を返します。
これが私のコードです:
var req = {
method: 'PUT',
url: presignedUrl,
headers: {
'Content-Type': 'text/csv'
},
data: <some file in base64 format>
};
$http(req).success(function(result) {
console.log('SUCCESS!');
}).error(function(error) {
console.log('FAILED!', error);
});
400 Bad Request
エラーの詳細:
<?xml version="1.0" encoding="UTF-8"?>
<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>Bearer someToken</ArgumentValue>
<RequestId>someRequestId</RequestId>
<HostId>someHostId</HostId>
</Error>
私が理解していないのは、なぜ400を返すのですか?と回避策は何ですか?
クライアントはおそらく、Authorizationヘッダーを使用する初期リクエストを送信しており、302で応答されています。このレスポンスには、Signatureパラメーターを持つLocationヘッダーが含まれています。問題は、最初のリクエストのヘッダーが後続のリダイレクトリクエストにコピーされ、承認と署名の両方が含まれることです。後続のリクエストから承認を削除すると、問題ありません。
これは私にも起こりましたが、Java/HttpClient環境です。Javaでのソリューションの詳細を提供できますが、残念ながらAngularJSではできません。
また、400の「無効な引数」は、S3 :: Presignerのconfig/credentialsが間違っているため、最初にURLに事前署名しているために表示される場合があります。 400を超えると、501の「実装されていません」という応答が発生する可能性があります。 Content-Lengthヘッダーを指定することで解決できました(必須ヘッダーとして here を指定)。うまくいけば、それは@arjunccに役立ち、署名付きURLでs3画像のアップロードをテストするときの郵便配達人の問題を解決しました。
これは遅すぎるかもしれませんが、@ mlohbihlerが言ったように、このエラーの原因は、Angularで設定したhttpインターセプターによってAuthorizationヘッダーが送信されたことにあります。基本的に、私はAWS S3ドメインを適切にフィルタリングして、JWT認証ヘッダーが自動的に取得されないようにしていませんでした。
Google社員の場合、Cloudfrontを介して署名済み(署名v4)S3リクエストを送信し、Cloudfront Origin設定で「バケットアクセスの制限」が「はい」に設定されている場合、CloudfrontはリクエストにAuthorizationヘッダーを追加します。このエラーが発生します。ただし、すでにリクエストに署名しているので、この設定をオフにして、セキュリティを犠牲にすることはできません。
メッセージは、1つの認証のみが許可されていることを示しています。あなたが送信したのは、認証パラメータ付きのURL、別の-Authorizationヘッダーです。