React and express communication with HTTPS enabled - reactjs

I'm trying to finalize an HTTPS connection for a production server I'm building but am running into issues with HTTPS.
I've tried a few guides on how to set it up individually for both react and node but cannot seem to get the connection completed.
Here's a simplified version of my server.js file for express:
const https = require('https');
const helmet = require('helmet');
const server = express();
server.use(helmet);
https.createServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
}, server)
.listen(port, () => console.log(`Listening on port ${port}`));
And my frontend build path in my package.json:
"scripts": {
"start": "set HTTPS=true && react-scripts start"
}
But when I go to https://localhost:3000 I get the following from the console and the screen is only white
Failed to load resource: net::ERR_EMPTY_RESPONSE index.js:1437
TypeError: Failed to fetch
Any thoughts on what I'm doing wrong? Thanks in advance for your time and for any help you can provide.

Related

Vite serving shader file with wrong (none) MIME type

I'm developing a BabylonJS application. BabylonJS PostProcess class appends .fragment.fx to a given file name and requests that from the server. When my local Vite (version 4.0.4) dev server serves this file the content-type header is empty. This causes Firefox to intepret it as type xml and fail. Chrome fails through a different, but I think related, mechanism.
How do you configure Vite to serve the *.fragment.fx static files as text/plain? I assume I need to disable the default middleware and write some custom code instead, like this: https://vitejs.dev/config/server-options.html#server-middlewaremode but I wanted to first check there wasn't something else going on / a simpler way to configure / fix this.
The vite dev server is started using vite --host --port 3000 --force and the config in vite.config.js is:
import { defineConfig } from 'vite';
export default defineConfig(({ command, mode }) => {
// if (command === 'serve') {
// return {
// // dev specific config
// }
// } else {
// // command === 'build'
// return {
// // build specific config
// }
// }
return {
resolve: {
alias: {
"babylonjs": mode === "development" ? "babylonjs/babylon.max" : "babylonjs",
}
},
base: "",
// assetsInclude: ['**/*.fx'],
};
});
* edit 1 *
I have seen there's a parameter ?raw that can be added to the URL however I don't control how BabylonJS forms the URL so I can't see how to make this work in this situation.
I followed these instructions and set up a dev server using express. I added this block of code above the call to app.use(vite.middlewares):
app.use("**/*.*.fx", async (req, res, next) => {
const url = req.originalUrl
const file_path = path.resolve(__dirname, "." + url)
const file = fs.readFileSync(file_path, "utf-8")
res.status(200).set({ "Content-Type": "text/plain" }).end(file)
})
I now start the dev server using the following script line in the package.json of "dev": "node server",
I could not find a way to solve this by configuring the default vite dev server.

localhost:3000 This site can’t be reached after installing http-proxy-middleware

I am building a newsletter sign-up form that uses .netlify-lambda to send my form submission to Mailchimp. I installed http-proxy-middleware to help the front end find the netlify-lambda folder. After writing the proxy setup code below my React start script stopped working. It appears the proxy setup below is interfering with localhost:3000.
My proxy setup looks like this
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
console.log('Using proxy...')
app.use(proxy('/.netlify/functions/', {
target: 'http://localhost:9000/',
"pathRewrite": {
"^\\.netlify/functions": ""
}
}));
};
If the target is localhost:9000 why is it interfering with localhost:3000?
When I start my Lambda server it says: Lambda server is listening on 9000.
I am also getting this error when trying to compile my client app.
crbug/1173575, non-JS module files deprecated
Short answer (for #lachnroll and anyone who might be encountering the same problem):
Please use const { createProxyMiddleware } = require("http-proxy-middleware") and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , instead of using const proxy = require('http-proxy-middleware'); and app.use(proxy("/.netlify/functions/" ...)...) , it should work.
Long one:
I've come across the same "can't be reached" thing in a React project when using http-proxy-middleware(2.0.3), until I changed const proxy = require('http-proxy-middleware'); and proxy("/.netlify/functions/" ...) to const { createProxyMiddleware } = require("http-proxy-middleware"); and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , I think the proxy has been removed, see: https://github.com/chimurai/http-proxy-middleware#readme

React build causes CORS error when there were no issues in development

I have built a React application (my first React application), and a C#.NET Core 3.1 Web API which serves data to the UI. I am deploying the API and the React application on the same server (Windows 10) with port 3030 for the API and port 3029 for the React build which was generated running the command "npm run build". The IIS site for the UI was pointed at the build directory.
In my development environment, running the application using the deployed API works and no proxy is needed. When deployed, my screen loads but no records are retrieved via the FETCH and instead there is a CORS error:
Access to fetch at 'http://localhost:3030/api/checking' from origin 'http://localhost:3029' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Why does this work when running out React in development out of Visual Studio Code with a hot load and why does this not work after the deployment? More importantly, how do I get this to work?
API code from Startup.cs
ConfigureServices method
services.AddCors(options => {
options.AddDefaultPolicy(builder => {
builder.WithOrigins(Configuration["AppSettings:CorsUrl"])
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Configure method
app.UseCors();
AppSettings.js code
"AppSettings": {
"CorsUrl": "http://localhost:3029"
}
React
I am storing my url within an .env file at the root level as shown below.
REACT_APP_API_URL=http://localhost:3030/api/checking
React Fetch command
In my checking.js component, the data is loaded and a FETCH is performed.
const SERVER_URL=`${process.env.REACT_APP_API_URL}`
function Checking() {
const [rowData, setRowData] = useState([]);
const [newData, setNewData] = useState(initialState);
const [displayModal, setModalDisplay] = useState(false);
const columnDefinitions = Columns();
const rowDataRef = useRef(rowData);
useEffect(() => {
fetch(SERVER_URL)
.then((response) => response.json())
.then((rowData) => {
setRowData(rowData)
rowDataRef.current = rowData;
});
}, []);
.
.
.
You need to set the Access-Control-Allow-Origin header. try the following methods to solve this error.
1.Clear your cookies and add Access-Control-Allow-Origin': '*' by Mod Header extension and
try again to check the fix .
2.Try using a middle interface to control your request and guide them
into the special rules.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
It turns out that I noticed a component misbehaving (ag-grid) and that caused me to run npm update. Once that was complete, I redeployed the build and everything is now working. I believe the update 'fixed' the issue.

How can I use firebase's firestore/admin sdk with next.js

I am building an application with firebase and next.js
I am fairly new to this set up, completely new to SSR, and the firebase docs are confusing me.
Currently, I am using firebase functions to run next.js, and that works like a charm. But now, I want to use firestore. I see two ways to use it in my project according to the docs (if I get it right). The first one is the 'web' solution which would not be benificial for me, because I believe it is not SSR, while the whole point of my app is being just that.
The other one is the 'node.js' solution, which runs on the firebase functions, this makes a lot more sense to me. The part I can't figure out, is using it with Next.js
In my current set up I am building my next.js application to the functions folder, inside the function folder I can reference the databaseref object I create with the 'node.js' solution, but how can I reference this before building my next application? So when I'm not in the functions folder?
Setup:
- src
- utils
- pages
- index.js
- signin.js
- // etc.
- functions
- next // this is the output folder of my 'src' build
- index.js
- // etc.
inside functions/index.js I could do:
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
let db = admin.firestore();
and use db to read and add to firestore, serverside (right?)
but all my code is in src/ before I build it and I don't think I could use it there. Should I structure my project differently? Or what should I do to be able to use db? Or, of course, another way to have a server side connection with my firestore.
Sorry for the bad answer. It's my first time. I was looking for cookie cuter code and seen that uor question wasn't answered.
I don't know the proper jargon. Yet, you have t run your app wit a custom server. Atleast that's wjhat I do to use firebase-admin. Notice here my answer is bad becase I acyually interfcae wit my client through socket.io. I only use firebase for client code and authentication
In package.json you are adding the script tag to stratfrom the command line
{
"scripts:
"server": "node server.js"
}
that makes it so you can run
$ npm run server
from the command line
~/package.json
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"server": "node server.js",
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "9.3.1",
"react": "16.13.1",
"react-dom": "16.13.1"
}
}
In the server.js fil you load up express for a server side rendering, probably can start your own http server with another post. However, as seen below I actullay use socket.io so it has that connection details
the key is right here thogh
he nextHandler() passes the control of the server to the next. So you can probably start an http server and use nextHandler()
app.get('*', (req, res) => {
return nextHandler(req, res)
})
~/server.js
const fs = require('fs');
const express = require('express');
const app = express();
const server = require('http').Server(app)
const firebaseAdmin = require('./services/dwf.firebase.admin.js');
const secureServer = require('https').createServer({
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
}, app)
const io = require('socket.io')(secureServer, {secure: true})
const User = require('../../users/user.manager.js');
let user = User(io,firebaseAdmin.auth(),firebaseAdmin.database());
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const nextApp = next({dev})
const nextHandler = nextApp.getRequestHandler()
// socket.io server
io.on('connection', socket => {
console.log(`Main Socket Opened by:\n ${socket.id}`);
socket.on('getDb',function(userId,refs,fn){
console.log("Getting Data")
firebaseAdmin.database().ref(refs).once('value',(snapshot)=>{
console.log(snapshot.val());
fn({body: snapshot.val()})
socket.emit('getDb',snapshot.val());
});
})
socket.on('disconnect', () => {
console.log(`Main Socket Closed by:\n ${socket.id}`);
});
})
nextApp
.prepare()
.then(() => {
app.get('/data/messages', (req, res) => {
res.json(messages)
})
app.get('*', (req, res) => {
return nextHandler(req, res)
})
secureServer.listen(PORT, () => console.log('#> Main Server ready for clients on https://0.0.0.0:PORT'));
})

Connecting Node.js app on Google Cloud App Engine to a Google Cloud SQL instance

I have a Node app which uses MySQL, connecting via a config json:
{
"client": "mysql",
"connection": {
"host": "something",
"user": "something",
"password": "something",
"database": "daimonion-db",
"debug": false
}
}
I've created a Google Cloud Platform SQL instance. I'm seeing an IP address and instance connection name.
I've also deployed the Node app to Google Cloud App Engine in a flexible environment.
How do I connect the Node app to the SQL instance? I'm seeing this explanation: https://cloud.google.com/sql/docs/mysql/connect-app-engine which tells me to add a settings string to my app.yaml to connect with either a Unix domain socket or TCP connection, but how do I connect to these from my Node app?
include beta_settings to app.yaml to enable cloud proxy on the instance in production, and specify the UNIX socket socketPath in config, so your flex app can connect to the instance via proxy.
socketPath should be in config only if the app is running in production on App Engine. For local development, the TCP socket is used with the proxy client, that you need to install and start with the following commands:
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
chmod +x cloud_sql_proxy
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
here's an example of Node app that connects and queries a Cloud MySQL instance using the proxy. The if statement permits the app to switch configuration dev-local/prod-appengine automatically, using environment variables .
app.yaml
runtime: nodejs
env: flex
env_variables:
SQL_USER: [SQL_USER]
SQL_PASSWORD: [SQL_PASSWORD]
SQL_DATABASE: [DATABASE_NAME]
INSTANCE_CONNECTION_NAME: [INSTANCE_CONNECTION_NAME]
beta_settings:
cloud_sql_instances: [INSTANCE_CONNECTION_NAME]
package.json
{
"engines": {
"node": "8.x.x"
},
"dependencies": {
"express": "4.16.3",
"mysql": "^2.15.0"
},
"scripts": {
"start": "node server.js"
}
}
server.js
const express = require('express');
const mysql = require('mysql');
const app = express();
var config = {
user: process.env.SQL_USER,
database: process.env.SQL_DATABASE,
password: process.env.SQL_PASSWORD
}
if (process.env.INSTANCE_CONNECTION_NAME && process.env.NODE_ENV === 'production') {
config.socketPath = `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}`;
}
var connection = mysql.createConnection(config);
connection.connect();
app.get('/', (req, res) => {
connection.query(
'SELECT * FROM entries', function(err, result, fields){
if (err) throw err;
res.send(result);
}
);
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
There are two ways to connect Cloud SQL instance from local desktop:
Example for postgresql
Using public IP and psql tool: https://cloud.google.com/sql/docs/postgres/connect-admin-ip
a. Add your external IP to Cloud SQL - CONNECTIONS - Authorized networks
b. Modify your connection.host to Cloud SQL instance public IP
Using cloud_sql_proxy tool and INSTANCE_CONNECTION_NAME: https://cloud.google.com/sql/docs/postgres/connect-admin-proxy

Resources