payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
23.67k stars 1.52k forks source link

[3.0.0-beta.32] CORS error in upload collection in live preview #6398

Closed heytyler closed 2 months ago

heytyler commented 4 months ago

Link to reproduction

No response

Describe the Bug

I am working on setting up a multi-tenant CMS with payload and ran into a CORS issue with live preview on upload collections. My CMS is running on localhost:3000 and my site is running on localhost:3001. If I edit any other block, the data populates through the live preview as expected, but when I add an image from my upload collection, it gives me a CORS error and doesn't populate the image url/data until I publish.

Error Recieved Access to fetch at 'http://localhost:3000/api/images?depth=2&where[id][in]=1' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

Attached is a video of the bug to help explain what I am talking about:

https://github.com/payloadcms/payload/assets/8431083/3a3a1171-4313-4256-8fb7-3b4608c82562

Please let me know if you need any more information, would love to find a way to get this to work. Appreciate the help and the hard work you guys have been putting in on 3.0!

Here is my payload.config. If you need me to drill into any of the values I can provide, but I figured I'd show how my CORS is set up:

export default buildConfig({
  admin: payloadAdmin,
  cookiePrefix: 'evogic',
  serverURL: process.env.NEXT_PUBLIC_PAYLOAD_URL || 'http://localhost:3000',
  cors: '*',
  globals: payloadGlobals,
  collections: payloadCollections,
  plugins: payloadPlugins,
  editor: payloadEditor,
  secret: process.env.PAYLOAD_SECRET || 'evogic',
  db: payloadDatabase,
  typescript: {
    outputFile: path.resolve(dirname, 'payload-types.ts'),
  },
  upload: { limits: { fileSize: 25000000 } },
  sharp,
})

To Reproduce

  1. Create Images Collection
    
    import type { CollectionConfig } from 'payload/types'

export const Images: CollectionConfig = { slug: 'images', access: { read: () => true, },

upload: { focalPoint: true, crop: true, imageSizes: [...sizes], formatOptions: { format: 'webp' }, mimeTypes: ['image/*'], adminThumbnail: 'thumbnail', },

admin: { useAsTitle: 'name', group: 'Media', },

fields: [...fields], }


2. Create Image Block
```typescript
import { Block } from 'payload/types'

export const ImageBlock: Block = {
  slug: 'imageBlock',

  fields: [
    {
      name: 'image',
      type: 'upload',
      relationTo: 'images',
    },
   ...otherFields
  ],
}
}
  1. Try to use image block within a page in live preview mode with the website accessing the CMS from another domain.

Expected Output / Response When Published

{
    "id": "6646b38773433b6a30cfe225",
    "width": "100%",
    "height": "100%",
    "size": "Original",
    "blockName": null,
    "blockType": "imageBlock",
    "image": {
        "id": 1,
        "alt": null,
        "project": 1,
        "updatedAt": "2024-05-17T01:21:13.409Z",
        "createdAt": "2024-05-17T01:21:13.409Z",
        "url": "http://localhost:3000/api/images/file/matadortyler_An_expansive_lush_green_lawn._Stock_photo._Adverti_dd380898-8bce-464a-b247-f9c733f84568.webp",
        "thumbnailURL": "http://localhost:3000/api/images/file/matadortyler_An_expansive_lush_green_lawn._Stock_photo._Adverti_dd380898-8bce-464a-b247-f9c733f84568-400x300.webp",
        "filename": "matadortyler_An_expansive_lush_green_lawn._Stock_photo._Adverti_dd380898-8bce-464a-b247-f9c733f84568.webp",
        "mimeType": "image/webp",
        "filesize": 204884,
        "width": 1456,
        "height": 816,
        "sizes": {...sizes},
        }
    }
}

Actual Output When Editing In Live Preview As you can see, the image is returning null and I am recieving the CORS error mentioned above.

{
    "id": "6646b38773433b6a30cfe225",
    "width": "100%",
    "height": "100%",
    "size": "Original",
    "blockName": null,
    "blockType": "imageBlock",
    "image": null
}

Payload Version

3.0.0-beta.32

Adapters and Plugins

db-postgres, storage-s3

heytyler commented 4 months ago

I also wanted to point out that if I add http://localhost:3001 to my CORS in payload.config, images work. But since this will be a multi tenant site with multiple domains being connected to it, this is less than ideal. I would prefer if images would function like the other fields do as they seem to work fine with the wildcard CORS setting.

jacobsfletch commented 2 months ago

Hey @heytyler thanks for the details on this. Look like the problem here is that we're setting credentials: include on our requests, which is not compliant with a wildcard CORS setting. The solution would be to explicitly whitelist each one of your domains. Something like this:

{
  "cors": ["http://localhost:3000", "http://localhost:3001"]
}
heytyler commented 2 months ago

Got it, thanks for looking into this!

gordonnl commented 1 month ago

@jacobsfletch It would great if we were able to set the cors wildcard for specific collections (ie media). Having to whitelist urls is cumbersome. Is there another workaround?

github-actions[bot] commented 4 weeks ago

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.