500 Internal Server Error when uploading to an AWS S3 bucket from Nuxt

Viewed 3145

I am trying to upload a file to AWS S3 using aws-sdk v3 from a Nuxt app's Vue Component.

Here's how I upload it.

<script>
export default {
...
methods: {
onSubmit(event) {
    event.preventDefault()
    this.addPhoto()
},
addPhoto() {
  // Load the required clients and packages
  const { CognitoIdentityClient } = require('@aws-sdk/client-cognito-identity')
  const { fromCognitoIdentityPool } = require('@aws-sdk/credential-provider-cognito-identity')
  const {
    S3Client,
    PutObjectCommand,
    ListObjectsCommand,
    DeleteObjectCommand,
  } = require('@aws-sdk/client-s3')

  const REGION = 'us-east-1' // REGION
  const albumBucketName = 'samyojya-1'
  const IdentityPoolId = 'XXXXXXX'

  const s3 = new S3Client({
    region: REGION,
    credentials: {
      accessKeyId: this.$config.CLIENT_ID,
      secretAccessKey: this.$config.CLIENT_SECRET,
      sessionToken: localStorage.getItem('accessToken'),
    },
  })

  var file = this.formFields[0].fieldName
  var fileName = this.formFields[0].fieldName.name
  var photoKey = 'user-dp/' + fileName
  var s3Response = s3.send(
    new PutObjectCommand({
      Bucket: albumBucketName,
      Key: photoKey,
      Body: file,
    }),
  )
  s3Response
    .then((response) => {
      console.log('Successfully uploaded photo.' + JSON.stringify(response))
    })
    .catch((error) => {
      console.log(
        'There was an error uploading your photo: Error stacktrace' + JSON.stringify(error.message),
      )
      const { requestId, cfId, extendedRequestId } = error.$metadata
      console.log({ requestId, cfId, extendedRequestId })
    })
},

...

}
</script>

The issue now is that the browser complains about CORS.

CORS error while s3 upload

This is my CORS configuration on AWS S3

s3 CORS Configuration

  1. I'm suspecting something while creating the upload request using SDK. (I'm open to use an API that is better than what I'm using).
  2. Nuxt setting that allows CORS.
  3. Something else on S3 CORS config at permissions
  4. Network tab on chrome dev tools shows Internal Server Error (500) for prefetch. (Don't know why we see 2 entries here) Network tab snapshot 1 without OPTIONS HTTP verb. This is called first Network tab snapshot 2 with OPTIONS HTTP verb Appreciate any pointers on how to debug this.
5 Answers

In the bucket policy use this

 {
"Version": "2008-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": [
            "s3:GetObjectAcl",
            "s3:GetObject",
            "s3:PutObject",
            "s3:PutObjectAcl",
            "s3:ListMultipartUploadParts"
        ],
        "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*",
        "Condition": {
            "StringLike": {
                "aws:Referer": "https://example/*"
            }
        }
    }
]}

and use the region of your bucket

const s3 = new aws.S3({
    apiVersion: 'latest',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID_CUSTOM,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY_CUSTOM,
    region: 'us-west-1',
})

enter image description here

I am having the same problem, but according to the docs you should be using Cognito Identity to access the bucket. Only in V3 for clients to be able to access the buckets from the browser you must use Cognito Identity to authenticate users in order to have access to bucket/object commands. Currently trying to implement, so I am not 100% how to do it just the process. Feel free to take a look. I hope this helps. ~~~~~~~~~~~~~~~~~~~~~~~~~~ | Cognito SDK Link: | https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html | Example: | https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-browser-credentials-cognito.html

I was doing multiple things wrongly here. Every answer on this post helped me make a little progress while debugging. Can't thank you enough!

  1. My bucket policy was not using role-based ALLOW/DENY that has to correspond to authenticated role on my cognito identity pool.
  2. Needed to rightly configure the Authentication provider as Cognito Userpool.
  3. Making sure the region is right. Cognito region could be different from S3 region.
  4. Make sure CORS policy includes relevant information like "Access-Control-Allow-Origin".
  5. Double check the token includes the right credentials. This comes very handy cognito decode-verify
  6. Was stand-alone testing from the browser. But this is not a good approach. Use an API server to take the file and push to S3 from there.
Related