Encountering a 500 Internal Server Error while attempting to upload to an AWS S3 bucket using Nuxt

I am facing an issue while attempting to upload a file to AWS S3 using aws-sdk v3 within a Vue Component of a Nuxt app.

Here is the process I follow for the upload:

<script>
export default {
...
methods: {
onSubmit(event) {
    event.preventDefault()
    this.addPhoto()
},
addPhoto() {
  // Loading necessary 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 current problem is that CORS is causing issues in the browser.

https://i.stack.imgur.com/8IV3N.png

This is my configuration for CORS on AWS S3

https://i.stack.imgur.com/GCKq6.png

  1. I suspect there might be an issue in creating the upload request using the SDK. (I'm willing to explore better API options)
  2. Check Nuxt settings for CORS permissions.
  3. Review other configurations related to S3 CORS permissions.
  4. Chrome dev tools Network tab shows Internal Server Error (500) for prefetch. (Not sure why there are 2 entries) https://i.stack.imgur.com/WPUtx.png https://i.stack.imgur.com/UIJaY.png Any guidance on debugging this would be highly appreciated.

Answer №2

To configure the bucket policy, incorporate the following:

 {
"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/*"
            }
        }
    }
]}

Be sure to specify the region of your bucket using the code snippet below:

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',
})

Answer №3

I am encountering a similar issue, and after reviewing the documentation, it appears that utilizing Cognito Identity is necessary to access the bucket. In V3, clients must leverage Cognito Identity for user authentication in order to perform bucket/object commands from the browser. I am currently in the process of implementing this solution and while I don't have all the details yet, feel free to explore further. Hopefully, this information proves helpful. ~~~~~~~~~~~~~~~~~~~~~~~~~~ | Learn more about Cognito SDK here: | https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html | Refer to this example for guidance: | https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-browser-credentials-cognito.html

Answer №5

After encountering several issues, I realized that I was making multiple mistakes. Fortunately, every response on this post contributed to my progress in debugging. I am truly grateful for all the help!

  1. I discovered that my bucket policy was not utilizing role-based ALLOW/DENY permissions that correspond to the authenticated role on my Cognito identity pool.
  2. It was crucial for me to correctly configure the Authentication provider as Cognito Userpool.
  3. I learned the importance of ensuring the region settings are accurate, as the Cognito region may differ from the S3 region.
  4. Verifying that the CORS policy includes necessary information such as "Access-Control-Allow-Origin" proved to be essential.
  5. I also double-checked that the token contained the correct credentials, using a helpful tool like Cognito decode-verify.
  6. While initially testing directly from the browser, I realized it is better to use an API server to handle the file and upload it to S3.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the correct way to configure Google Analytics on my Vue web application?

I am currently working on a Vue component called calculator.vue and I have included the necessary code for the plugin in my main.js file as shown below: import App from './App.vue' import vuetify from './plugins/vuetify' import "./ ...

Using a temporary variable within a Vue loop

Currently, I am utilizing Vue along with Vuetify to create a menu containing links using the treeview component. The data source I'm working with is a nested JSON structure. The issue I am facing is regarding linking the parent "to" with its children ...

Is there a problem encountered when attempting to pass an array value as a string using props in Vue.js?

<template> <div> <div v-for="piza in pizas" :key="piza.pname"> {{ piza.pname }} <List :content="matchpizza" :pname="piza.pname" :qname="quantitys.qname" /> </div> </div> </template> <scr ...

Troubleshooting: Unable to use setOption method in Vue-Dropzone

I am attempting to dynamically set the URL on a dropzone element's options. The documentation specifies that you should use the setOption method to change options after initialization. Here is what I have tried: var url = 'http://myurl' th ...

Flatten information from an object containing multiple objects within an array

In my current project using Vue, I am making an API call to retrieve data from my Laravel backend (nova). The returned data is structured in the following way. The data consists of an array, which contains arrays of objects. Each array represents a record ...

What are the possible arguments for the event type onInput?

While diving into the world of html / javascript / vue, I stumbled upon the following code snippet. <input type="text" onInput="doAction(event);"> <script> var mesdata = { message: 'type your m ...

Can the `lang` attribute be used in a `style` tag to specify the CSS preprocessor language for VueJS? Are there any disadvantages to using this method?

Occasionally, I notice people incorporating code like this: <style lang="scss"> ... </style> <style lang="stylus"> ... </style> I checked the documentation for the style tag and found that lang is not a valid a ...

Guide to creating flexible routes with multiple changing parameters in Vue 3 using Vue Router

What is the best way to implement dynamic routes with multiple dynamic parameters in any order using Vue 3 and Vue Router? These parameters should be able to be passed in any order. In our web application, we have over 500 views which makes it impractic ...

Trouble updating Vue 2 project using vue-cli due to npm update failure

I set up a Vue 2 project using vue-cli and attempted to execute npm update. Unfortunately, I encountered the following error: { npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a href="/cdn-c ...

Utilizing Vue Nuxt plugins with fetch() in website layouts

Wondering if I'm on the right track here, it seems a bit clunky. Currently, I am utilizing a plugin in a Nuxt layout component and aiming to dynamically generate content within the layout using the new fetch() api. async fetch() { this.notifications ...

What are some ways to rejuvenate a computed property?

Is there a way to refresh the data displayed in someData after it has been updated and saved on the server? I have tried using $recomputed('someData'), but it's not working as expected. I believe I might need to utilize a Promise, but I&apo ...

Travis-CI build encountering errors, however, local tests and builds run smoothly

I'm encountering difficulties getting my unit test to pass with Travis. When running the tests locally, I don't see any errors (unit/e2e)... If you'd like to see the log file, it can be found here in the Travis build log There are numerous ...

Is there a way to directly send a file to S3 without needing to create a temporary local file?

Looking for a solution to upload a dynamically generated file directly to amazon s3 without saving it locally first? Specifically using Python. Any ideas or suggestions? ...

The functionality of Nuxt's asyncData is restricted when attempting to access data from authorized express routes

Setting up an online store. I began with the products, which can be pulled without authorization but require it for editing. The process is smooth so far, probably because it's happening on the client side where authentication information is included ...

What is the process for adding an additional level to an Object for an item that is not predefined?

The primary concern at hand is as follows: Retrieve JSON data from the server Populate a form with the data Serialize the form Create a JSON object with the correct structure Send the JSON object back to the server I am facing challenges specifically on ...

Executing an external script in Nuxt after re-rendering: Best practices?

Looking for a solution in Nuxt/Vue to properly execute an external script (hosted by a third party) after the DOM has successfully rerendered on every route. The challenge arises when using a script that dynamically adds elements to the dom, causing confl ...

Attempted to identify whether an item exists in an array, and if it does, then add the item to the array; if not, then perform

Allow me to make some clarifications as it might be a bit confusing initially. This project I'm working on is for school. I don't expect anyone to do it for me, but I need help with a specific part. I'm creating a simple shopping cart using ...

Utilizing mustache template strings within the href attribute in VueJS

How can I incorporate a mustache inside an href attribute within the context of Vue.js? After researching various solutions, I attempted to apply them to my code. Mustache inside an href How to pass a value from Vue data to an href? Reddit thread on us ...

Troubleshooting: Vue.js file upload encountering OPTIONS 404 error

In my express app, I have configured CORS and most of the routes are working fine. However, I'm facing an issue with a specific component used for uploading images: <input type="file" class="form-control" @change="imageChanged"> <div @clic ...

Working with conditional class binding in Vue.js based on width

I am new to using Vue.js and I have a question regarding how to utilize conditions with the v-bind directive. Here is the code where I encountered an error: <input type="text" class="form-control" v-bind:class="{'is-i ...