fastify / fastify-cors

Fastify CORS
MIT License
419 stars 59 forks source link

CORS Issue with Fastify and Socket.IO Configuration #303

Closed virangaj closed 4 months ago

virangaj commented 5 months ago

Prerequisites

Fastify version

4.27.0

Plugin version

No response

Node.js version

18.18.0

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

23H2

Description

Description: I am encountering a CORS issue while setting up my Fastify server with Socket.IO. Despite configuring the CORS plugin, my frontend is unable to communicate with the backend due to CORS errors.

Steps to Reproduce:

  1. Set up a Fastify server with the following dependencies:
  1. Configure the server to use CORS and Socket.IO as shown in the provided code snippet.
  2. Attempt to connect from a frontend application.

Expected Behavior: The frontend should be able to communicate with the backend without CORS issues.

Actual Behavior: The frontend is receiving CORS errors when attempting to communicate with the backend.

Fastify Server Code:

const fastify = require("fastify")({ logger: true });
const socketIo = require("fastify-socket.io");
const path = require("path");
const axios = require("axios");
require("dotenv").config();

const PORT = process.env.PORT || 3001;
const API_BASE_URL = process.env.BACKEND_SERVER;

fastify.register(require("@fastify/cors"), {
  origin: (origin, callback) => {
    if (!origin) return callback(null, true);
    const allowedOrigins = ['http://your-frontend-url.com', 'http://another-allowed-url.com'];
    if (allowedOrigins.indexOf(origin) !== -1) {
      return callback(null, true);
    } else {
      return callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'OPTIONS'],
});

fastify.ready((err) => {
  if (err) throw err;

  fastify.io.on("connection", (socket) => {
    fastify.log.info("A user connected");

    socket.on("joinRoom", async ({ id, token }) => {
      socket.join(`room-${id}`);
      try {
        const messages = await fetchMessages(id, token);
        socket.emit("updateMessages", { data: messages, firstRender: true });
      } catch (error) {
        fastify.log.error("Error fetching messages:", error);
      }
    });

      socket.on("disconnect", () => {
      fastify.log.info("User disconnected");
    });
  });
});

Access to XMLHttpRequest at 'http://your-frontend-url.com/chat' from origin 'http://your-frontend-url.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Link to code that reproduces the bug

No response

Expected Behavior

The frontend should be able to communicate with the backend without CORS issues.

mcollina commented 5 months ago

Thanks for reporting!

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

climba03003 commented 5 months ago

Please provide the screenshot in broswer or cURL about the headers for both request and response. You can mask the sensitive information. I would like to double confirm is the header properly sent.

For example, is the browser providing the Origin header.

If you are using reverse proxy in between, please also check if the headers are hide by that proxy. It is often that the proxy is not properly proxy CORS headers and requires some manual config.

virangaj commented 4 months ago

image This is what I'm getting in my browser

climba03003 commented 4 months ago

This screenshot is not going to helps. You should provide that contain the headers for both request and response.

climba03003 commented 4 months ago

I am closing the issue because I believe it is the problem related to socket.io. socket.io used to be overriding the request handling of fastify, so you should configure the CORS from socket.io side.

virangaj commented 4 months ago

Yes, you are correct... the issue is in socket.io side, Thank you