Home > Enterprise >  Uploading a video to the presigned URL from Frontend
Uploading a video to the presigned URL from Frontend

Time:03-25

I have used my backend code to generate the presigned URL and then used that URL to upload a video that was recorded during the session. I am using the below piece of code in the frontend(React JS) to upload the video the preflight seems to fail with 403 Forbidden and the post request fails with cors error. Please find below the details:

Code used:

static async uploadVideoToS3(url, body) {
        try {
            const myHeaders = new Headers({ 'Content-Type': 'video/mp4', 'mode': 'no-cors' });
            const response = fetch(url, {
                method: 'POST',
                headers: myHeaders,
                body: body
            });
            return response;
        } catch (error) {
            toast(error);
            console.log(error);
        }
    } 

Console error: Access to fetch at 'https://xxxxxxxxxx' from origin 'http://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Note: Changed the presigned URL to xxxxxxxxxx to avoid leaking the details in the post here.

Could the issue be that I am running all this on localhost? Or Is the CORS Configuration on the AWS S3 Bucket causing this issue? or Is there any header missing in my request?

I found a post that had a similar issue: Getting 403 (Forbidden) when uploading to S3 with a signed URL where the OP responded that the issue was resolved but they never mentioned the resolution.

CodePudding user response:

Try adding proxy to package.json file and add the url of the server you're sending your request to, In your case localhost:5000

"proxy": "http://localhost:5000"

Then restart your app with npm start and change the url in your component, if you are doing it like

const res = fetch('https://localhost:5000/api/user')

then change it and do it like below

const res = fetch('/api/user')

If the above solution doesn't work then there might be a problem with your backend.

CodePudding user response:

I thought so too that as I was trying to hit the URL from local which isn't served on a secure host (HTTP) was causing the issue. So I deployed the app on a dev environment but faced the same issue. After some research, I was able to fix the issue. It seems that I needed to modify the CORS configuration of the S3 Bucket that I was trying to generate the pre-signed URL from.

Before generating the pre-signed URL, I added the below piece of code which changes the CORS configuration of the S3 bucket and since I was accessing it from my local as well I have put the Allowed Origins as * for now but before moving to production, I will change it to the prod URL.

//passing AWS credentials            
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
            
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                    .withRegion(clientRegion)
                    .build();
//Creating CORS List to update the CORS Configuration
                List<String> allowedHeaders=new ArrayList<String>();  
                allowedHeaders.add("*");
                
                List<AllowedMethods> allowedMethods=new ArrayList<AllowedMethods>();  
                allowedMethods.add(0, AllowedMethods.GET);
                allowedMethods.add(1, AllowedMethods.PUT);
                
                List<String> allowedOrigins=new ArrayList<String>();  
                allowedOrigins.add("*");
                
                List<String> exposedHeaders=new ArrayList<String>();  
                exposedHeaders.add("GET");
                exposedHeaders.add("PUT");
                
                CORSRule cors = new CORSRule();
                cors.setAllowedHeaders(allowedHeaders);
                cors.setAllowedMethods(allowedMethods);
                cors.setAllowedOrigins(allowedOrigins);
                cors.setExposedHeaders(exposedHeaders);
                cors.setMaxAgeSeconds(3600);
                
                //Assigning CORS List to CORS Configuration
                BucketCrossOriginConfiguration CORSConfiguration = new BucketCrossOriginConfiguration();
                CORSConfiguration.withRules(cors);
                
                //Updating CORS Configuration
                s3Client.setBucketCrossOriginConfiguration(bucketName, CORSConfiguration);

Alternatively, you can modify the CORS from the frontend/other languages as well, reference: Javascript: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketCors-property Other Languages: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html#API_PutBucketCors_SeeAlso

  • Related