'Azure function CORS configuration with SignalR Service not working

I'm trying to connect to SignalR Service Azure function from a react front end.

In front

const urlRoot = 'http://localhost:7071/api';
const connection = new HubConnectionBuilder()
    .withUrl(urlRoot
    )
    .build();

In Azure function I allow CORS in local.setting.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureSignalRConnectionString": "xxxxxx"
  },
  "Host": {
    "CORS": "*",
    "CORSCredentials": false
  }
}

But when I run my app a request is triggered to http://localhost:7071/api/negotiate?negotiateVersion=1 ( I don't know why HubConnectionBuilder() is adding negotiateVersion=1

The problem is that I'm getting Cors error even after adding authorization in local.settings.json

Access to XMLHttpRequest at 'http://localhost:7071/api/negotiate?negotiateVersion=1' from origin 'http://localhost:3000' 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'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.



Solution 1:[1]

If running locally you need to set

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureSignalRConnectionString": "xxxxxx"
  },
  "Host": {
    "CORS": "http://localhost:3000",
    "CORSCredentials": true
  }
}

Where your react app is running locally on post 3000. As the wildcard is not supported.

Solution 2:[2]

The problem here is not "just" the CORS configuration.

The way to connect to the Azure SignalR Service is a little different from the way we connect to a conventional SignalR hub.

First, we need to access the "/api/negotiate" endpoint and acquire the access token, them, with the token, we can connect to the service.

Follow below a code that I'm using:

export const myComponent = () => {

    const [signalRConnection, setSignalRConnection] = useState(null);

    useEffect(() => {

        //Get the access token...
        axios.post("http://localhost:7071/api/negotiate?negotiateVersion=1")
           .then((response) => {
                
                const options = {
                    accessTokenFactory: () => response.data.accessToken,
                };
            
                //Connect using the token
                const newConnection = new HubConnectionBuilder()
                  .withUrl("http://localhost:7071/api", options)
                  .withAutomaticReconnect()
                  .build(HttpTransportType.None);

               setSignalRConnection(newConnection);
           });
       }, []);

   useEffect(() => {
    
       if (signalRConnection) 
       {
           signalRConnection
               .start()
               .then((result) => {
               
                   console.log("Connected SignalR Hub!");

                   signalRConnection.on("myEvent", (message) => {
                     /* Do something.... */
                   });
                });
              })
               .catch((e) => console.log("Connection failed: ", e));
        }
   }, [signalRConnection]);

};

And about the CORS configuration, you can't use "*" to specify the client application.

Use something like that

{
  "Host": {
    "CORS": "http://localhost:3000",
    "CORSCredentials": true
  }
}

Solution 3:[3]

Login to your Azure account and make sure CORS is enabled and http://localhost:3000 is added CORS sETTING

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John
Solution 2 Julio Schurt
Solution 3 neuvee