Repository navigation
|
Hi. How do I get the remote IP address, from within, say, my I know that these apps are often run behind a proxy and if it's set up right, I can use the X-Forwarded-For header, if the proxy is one that I set up and run. But what if I'm not behind a proxy, such as in development? Or what if I'm interested in which of my proxies a request came from? I know that react-router's framework mode uses express behind the scenes. In the documentation for express, it says that the request object should have a property called But the request objects that my loader function gets does not have that property, or, as far as I can tell, any other way to find the remote IP address. So, is there a way to find the remote IP address? |
Replies: 1 comment 1 reply
|
The The built-in I checked this with React Router 8.5.1 ( // app/context.ts
import { createContext } from "react-router";
export const clientIpContext = createContext<string | undefined>();// server/app.ts
import { RouterContextProvider } from "react-router";
import { createRequestHandler } from "@react-router/express";
import express from "express";
import { clientIpContext } from "~/context";
export const app = express();
// Only if the app is reachable solely through proxies you run.
// A NUMBER is the count of proxies in front of the app.
// The string "1" (e.g. straight from process.env) would mean "trust the proxy at IP address 1".
app.set("trust proxy", 1);
app.use(
createRequestHandler({
build: () => import("virtual:react-router/server-build"),
getLoadContext(req) {
const context = new RouterContextProvider();
context.set(clientIpContext, req.ip); // req.socket.remoteAddress = the TCP peer only
return context;
},
}),
);// any loader or action
export function loader({ context }: Route.LoaderArgs) {
const ip = context.get(clientIpContext);
// ...
}
The same code also works in development: with
Without Express: // server/app.ts
import { createRequestListener } from "@react-router/node";
export const listener = createRequestListener({
build: () => import("virtual:react-router/server-build"),
getLoadContext(request, client) {
const context = new RouterContextProvider();
context.set(clientIpContext, client.address);
return context;
},
});
// node-server.mjs: http.createServer((await import("./build/server/index.js")).listener).listen(3000)Tested the same way: the direct request gives Only turn on |
The
Requestyour loader gets is a Fetch APIRequest, and it has no notion of the remote address. The address lives on the Node/Express request. You pass it in through the load context, and that needs a server where you controlgetLoadContext.The built-in
react-router-servehas no such hook. It callscreateRequestHandler({ build, mode })withoutgetLoadContextand does not settrust proxy(cli.ts). With it, the loader can't see the IP. Use a custom Express server instead; the officialnode-custom-servertemplate already has one, and the Express adapter calls yourgetLoadContext(req, res)for every request (server.ts).I checked this with React Router 8.5.1 (
npx create-react-router@8.5.1 -…