'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 |