WTFranklin
WTFranklin

Reputation: 2568

Error executing "PutObject" 400 bad request aws

I'm very new to working with AWS and I'm working through the example AWS gives to use putObject found here https://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjSingleOpPHP.html

All I'm trying to at this point is just upload any object to my S3 bucket using the AWS SDK like in the example, but I get an error saying 400 Bad Request (the full output is below). The bucket I'm trying to write to is intentionally not public because I don't want the entire bucket to be accessible. I'm not exactly sure if this is the problem, but if it is I'm not sure how to give my code access to write to the bucket and the documentation doesn't have an example for that. If this isn't the problem, then I'm not sure what else might be going wrong.

I've edited my php to include the bucket I'm trying to access and my own keyname, which my understanding is supposed to be the filename you want to use once the object is uploaded. I keep getting this error though:

Error output:

Error executing "PutObject" on "https://frank-transcribe-mediaconvert.s3.amazonaws.com/032420-test-upload.txt"; AWS HTTP error: Client error: PUT https://frank-transcribe-mediaconvert.s3.amazonaws.com/032420-test-upload.txt resulted in a 400 Bad Request response: InvalidTokenThe provided token is malformed or other (truncated...) InvalidToken (client): The provided token is malformed or otherwise invalid. - InvalidTokenThe provided token is malformed or otherwise invalid.

Here is my php code:

<?php

    require 'vendor/autoload.php';

    use Aws\Sts\StsClient;
    use Aws\S3\S3Client;
    use Aws\S3\Exception\S3Exception;

    $bucket = 'frank-transcribe-mediaconvert';
    $keyname = date('mdy') . '-test-upload.txt';

    $s3 = new S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1'
    ]);

    try {
        // Upload data.
        $result = $s3->putObject([
            'Bucket' => $bucket,
            'Key'    => $keyname,
            'Body'   => 'Hello, world!',
            'ACL'    => 'public-read'
        ]);

        // Print the URL to the object.
        echo $result['ObjectURL'] . PHP_EOL;
    } catch (S3Exception $e) {
        echo $e->getMessage() . PHP_EOL;
    }

?>

Upvotes: 1

Views: 3486

Answers (1)

ArSeN
ArSeN

Reputation: 5258

Your upload code looks just fine. Having buckets writeable is not a good practice and from your question I gather that you did not set it to publicly writeable either.

Therefore, as long as you are not running this on an AWS instance that can authenticate against the API by its IAM role, you will have to pass credentials to the S3 client.

Here is an excerpt from the docs:

$credentials = new Aws\Credentials\Credentials('key', 'secret');

$s3 = new Aws\S3\S3Client([
    'version'     => 'latest',
    'region'      => 'us-west-2',
    'credentials' => $credentials
]);

You are correct that the "Key" in your code is the filename (S3 sees itself as a key-value object storage, where the directory and filename is the key and the value is the file content, thats why it is called key).

However, the "key" for the credentials - in conjunction with the secret - are AWS access keys that you can set using IAM. If you don't know how to do that, I recommend you read Managing Access Keys (Console) in the AWS docs.

Also note that the IAM user that you create the access keys (key and secret) for does need to have the proper permissions to do via S3 what you want to do.

Upvotes: 1

Related Questions