Fawad Khalil
Fawad Khalil

Reputation: 33

Unable to fix CORS policy on Google Cloud storage

I am trying to upload files to Google cloud storage's bucket from a React app. I have enabled CORS setting for the bucket but it seems that I cannot still get access from the web app. I am getting the following error:

Access to fetch at 'https://storage.googleapis.com/my_unique_bucket/ABCdio%20Vi?GoogleAccessId=storage-ucardia%40ucardia-297520.iam.gserviceaccount.com&Expires=1612456695&Signature=oxb2LVj22hc4%2FsnskKIwaq%2BK9qq88yAmnAGN1pbRJ%2BPJ2d68%2BHRRBYS24xPNwBLSkVktsjSWTBBoWv5tTkCuUAzG3Q2Q51gLdoaLUmFyGt8a4hgKJ94DeTaAJL0Hf0rwz0sNx6SkSdqrrQF%2BGlRH4HYI10JBQHuw3%2BQMPIW%2FRXTlfcvjdCkdRT9vX6twjBrC4bdIijvB31SvxbipQHWuhh6QjlKtybp3OW8kV2tY00KNWv0pE98%2FCRDBikzVkyZwM8WOYEXWUuxY9lem9LYjkBo%2BafQECApvkTQVjg%2FWJo%2BUCTVpnO5wKL58BN2QCqkmG%2FIPAwg0ptQJVMcxFhfCZw%3D%3D' from origin 'https://dashboard-fe.uc.r.appspot.com' 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.

The CORS setting in JSON file is following:

[]

However, I has tried with the setting specifying the web URL and PUT method in the JSON as well, but didn't work.

UPDATE 1:

Node.js API:

const storage = new Storage({
    keyFilename: path.join(__dirname, '../../../projectId.json'),
    projectId: 'projectId',
});

storage.getBuckets().then((x) => {
    console.log(x);
});

const generateSignedUrl = async (req, res) => {
    const { filename, filetype } = req.query;
    // These options will allow temporary read access to the file
    const options = {
        version: 'v2', // defaults to 'v2' if missing.
        action: 'write',
        expires: Date.now() + 1000 * 60 * 60, // one hour
        contentType: 'application/x-www-form-urlencoded',
    };

    try {
        // Get a v2 signed URL for the file
        const [url] = await storage.bucket('my_unique_bucket').file(filename).getSignedUrl(options);

        res.status(ok).json({ data: url, message: GENERATE_SIGNED_URL_SUCCESS, status: true });
    } catch (error) {
        res.status(internalServerError).json({ error, status: false, message: GENERATE_SIGNED_URL_FAILED });
    }
};

Reactjs Client:

export const putFile = async ({ url, file }) => {
    const method = 'PUT';

    return await fetch(`${url}`, {
        body: file,
        method,
        headers: {
            // Accept: file.type,
            'Content-Type': file.type,
            'Access-Control-Allow-Origin': '*',
        },
    });
};

UPDATE 2: This link says that it is an issue with the formation of the URL but I am getting the URL as presigned URL from the google cloud storage NPM package. BTW I have followed this link to set up the mechanism but it seems I am missing something very obvious.

Upvotes: 2

Views: 8705

Answers (2)

Kuday
Kuday

Reputation: 138

Assuming you've already tried setting the CORS policy for your bucket and still don't have a way around it, here's something that helped in my case:

As per this article the public URL provided from by Google does not inherently set the CORS headers. Including your bucket name in the domain for the URL should fix it.

storage.googleapis.com/your-bucket ⬅ will not have headers

your-bucket.storage.googleapis.com ⬅ will have cors headers

For example:

Current URL: storage.googleapis.com/your-bucket-name/file-name.mov

New URL: your-bucket-name.storage.googleapis.com/file-name.mov

Upvotes: 4

Samuel Romero
Samuel Romero

Reputation: 1253

Sorry for the delay in my response. I noticed something curious in your code. You have this configuration in your JSON file

[]

However, in your react client you have this

headers: {
            // Accept: file.type,
            'Content-Type': file.type,
            'Access-Control-Allow-Origin': '*',
        }

If you have [] in your JSON file, you are removing CORS from a bucket. Nevertheless, you are still sending the value. You need to add this to your JSON file to set the CORS in your bucket.

[ { "origin": ["*"], "method": ["PUT"] } ]

Here you can find an article about it.

Upvotes: 5

Related Questions