I have created a basic app with React SPA and Node.js & Express web API using this sample
https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/5-AccessControl/1-call-api-roles
The app is running fine locally- both front-end authentication and backend API calls are working as expected.
When I deploy the app on Azure, the front end is working fine but the backend API calls are not working at all and they timeout- I do not see any logs in the backend either. While locally, I can see all the console.logs on invoking the API calls.
I have tried many changes to troubleshoot Node.js app mentioned below and I am seeking guidance on what other settings/ changes might help to get the Node.js app running on Azure.
- I tried to run the backend manually in Azure as well in /wwwroot/server –
node app.js
and I see the log saying API is listening, but API calls timeout.
-
The web.config.js is pointing to
server/app.js
-
On Azure, the React app successfully runs only on
port 443
as below and doesn’t run at all when set to some other PORT:
client/package.json
...
"scripts": {
"start": "set PORT=443&& react-scripts start",
...
Locally it runs on all the ports when specified as below:
client/package.json
...
"scripts": {
"start": "set HTTPS=true&&set SSL_CRT_FILE=certificate.crt&&set SSL_KEY_FILE=privateKey.key&&set PORT=3000&& react-scripts start",
...
- fetch calls timeout on Azure
client/fetch.js
export const getTest = async (env) => {
// const accessToken = await getToken();
const headers = new Headers();
// const bearer = `Bearer ${accessToken}`;
// headers.append("Authorization", bearer);
const options = {
method: "GET",
headers: headers,
};
return fetch(protectedResources.apiList.test, options)
.then(response => response.json())
.catch(error => console.log(error));
}
- In
server/app.js,
locally, both commenting out and using the authentication logic works for API calls, but none works on Azure. - Also tried to run Node.js on both http and https. PS. locally only HTTPS works for both client and Node as redirectUri is https
server/app.js
const path = require('path');
const express = require("express");
const cors = require("cors");
const axios = require("axios");
const PORT = process.env.PORT || 8080;
require("dotenv").config();
const app = express();
app.use(cors());
app.use(express.json());
//app.use(express.static(path.resolve(__dirname, '../client/build')));
app.get("/api/test", (req, res) => {
res.json("hi");
});
//...other bearer token code
// https.createServer(httpsOptions, app).listen(PORT, () => console.log(`Server is running on port ${PORT}`));
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
2
Answers
After giving a couple of days of trying to figure out the solution, I decided to reverse engineer the code and start with a version that worked locally and on Azure.
Then incrementally copied my final code (with Azure issue) and made small builds and releases so I could track what could have gone wrong.
Eventually, I got the final app working with the same code (that had the deployment problem on azure). Not sure what the problem was with Azure deployment earlier.
If you are using azure VPS, then enable the ports from the azure user panel. As azure restricts ports that are even enabled from the windows firewalls. So yea make sure, ports are enabled from the user panel/control panel.