I am making a React frontend with an express backend. For context, I am making a contact form that both stores information in a MySQL database and sends an email to myself and the user. Currently, whenever a request is sent through the React frontend, the IP is always 127.0.0.1. I assume this is because the same server is hosting the frontend, however, I was hoping there would be a workaround to get the actual IP to prevent spam without blocking everyone.
app.js (express)
const express = require("express");
const env = require("./extensions/env");
const { con } = require("./extensions/sql");
const apiRouter = require("./routers/apiRouter");
const { logRequest } = require("./middleware/logRequest");
const path = require("path");
const app = express();
app.use(express.json());
app.use("/api", logRequest);
app.use("/api", apiRouter);
app.use(express.static("build"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "build", "index.html"), (err) => {
if (err) {
res.status(500).send(err);
}
});
});
app.listen(env.express.PORT, () => {
console.log(`App live on ${env.express.URL}`);
if (env.LOCAL_ADDRESSES.length > 0) console.log(`On your local network: ${env.LOCAL_ADDRESSES.map(a => `http://${a}:${env.express.PORT}`).join(", ")}`);
con.connect((err) => {
if (err) {
console.log("Unable to connect to MySQL.");
}
else {
console.log("Connected to MySQL!");
}
})
});
logRequest.js Middleware (express)
const { v4: uuid } = require("uuid");
const generalizePath = require("../extensions/generalizePath");
const { db } = require("../extensions/sql");
const logRequest = async (req, res, next) => {
const requestId = uuid();
const method = req.method;
const path = generalizePath(`/${req.path}`);
const ip = req.headers["X-Forwarded-For"] || req.socket.remoteAddress;
const timestamp = Date.now();
req.requestId = requestId;
req.ip = ip;
req.timestamp = timestamp;
const printf = (str, amt) => {
if (amt-str.length < 1) return `${str}`
return `${str}${[...Array(amt-str.length)].map(_ => " ").join("")}`
}
console.log(`n${printf("Method", 8)} ${printf("Path", 16)} ${printf("Request ID", 37)} ${printf("IP", 18)} Date/Time`)
console.log(`${printf(method, 8)} ${printf(path, 16)} ${printf(requestId, 37)} ${printf(ip, 18)} ${new Date(timestamp).toISOString().slice(0, 10)} ${new Date(timestamp).toISOString().slice(11, -5)} GMT`)
// if (["127.0.0.1","::1"].includes(ip)) return next();
await db.requests.insert({ requestId, method, path, ip, timestamp });
return next();
};
module.exports = {
logRequest
};
Request (React)
fetch("/api/contact", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({email: "[email protected]")
});