Proxy issue on calling express server from react server - node.js

Hey guys i was just working out on Proxy for calling nodejs server from react server, so after adding "proxy": "http://localhost:5000/"
to my package.json file in react i was able to redirect to localhost:5000 (which is running my node server) but it seems that Proxy only works with fetch and axios as
axios.get("/api/currentuser")
redirects me to localhost:5000
but then when i try this on anchor tag like
<li>Login with google</li>
it doesn't takes me to localhost:5000
so is there any way that sometimes working with tag if i need to stay at localhost:3000i should be there and whenever i need i can go to localhost:5000 ???
cause not for all anchor tag i need to redirect to localhost:5000

According to this post and react documentation you can use the file setupProxy.js to redirect requests based on certain criteria to a proxy and it also seems to work for href property.
You would have to adapt the example code:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use('/api', proxy({
target: 'http://localhost:5000',
changeOrigin: true,
}));
};
to your requirements. You can use pattern matching on the api paths, so it should not be a problem. Hope this helps! :)

Related

How to rewrite request path using http-proxy-middleware in a react app?

I am using http-proxy-middleware in my react app, where I have a setup like this:
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
"/api/v1",
createProxyMiddleware({
target: "https:test.com/",
changeOrigin: true
})
);
};
Some api requests of my applications has request url as:
http://localhost:3000/products-and-details/api/v1/proxy/trend/api/v1/listProducts
which I want to change it to:
http://localhost:3000/api/v1/proxy/trend/api/v1/listProducts.
To achieve this I am modifying request paths before requests are send to the target using pathRewrite as below:
pathRewrite: {
'^/products-and-details': ''
}
However this doesn't seem to work and the request url remains the same with no changes. Can anyone please help to point out what am I doing wrong here?
Edit: My http-proxy-middleware dependency has a version ^2.0.3
My senior colleague helped me to fix this. It seemed that the request, http://localhost:3000/products-and-details/api/v1/proxy/trend/api/v1/listProducts was not at all intercepted by the proxy. Hence, to intercept those requests we have to make sure to include it in the context for our proxy middleware.
So, in my case it was as described below:
app.use(["/api/v1", "/products-and-details/api/v1"])
And then use PathRewrite to modify request paths before the actual request is made to server as depicted below:
pathRewrite: {"/products-and-details": ""}

React proxy how to prevent from outside world

I have a react js application working on port 3000 and a nodejs working on port 4000.
I am using setupProxy as
const createProxyMiddleware = require(`http-proxy-middleware`)
module.exports = function (app) {app.use('/api/*', createProxyMiddleware({ target:http://localhost:4000', changeOrigin: true, }))}
On server, running on port 4000, I am using cors as:
app.use(cors((cors.CorsOptions = { origin: `http://localhost:3000`,})))
The application on localhost:3000 is exposed as https://example.com/
I have an end point on Node server as /api/todos which perfectly accessible from react client.
Outside world can post for example https://example.com/api/todos. How to prevent this?
There was a similar post I answered a few days ago here
How to launch a command on the server from a web page ( nodejs )
With that being said though, and maybe a TLDR you need a way to protect your route. This is where you have two options really.
Use JWT
Use 'sessions' (this would assume you are not connecting / posting from outside the main application so it shares a session between frontend / backend)
From what it sounds like, the application / front-end are not bound together so option 2 may not be an options.
With option one you would create a JWT token from the front end. This token would contain an encoded string that can only be decoded on the server. You send this token with your post or get request and have middleware to decode and verify the token is valid, if not, don't let it post to the route.

Can't fetch POST request from node.js when server is hosted in specific path

I have a website built with wordpress and one of it's routes serves a node.js server.
Let's suppose https://www.wordpress.com/ is the domain and the node.js route is https://www.wordpress.com/node.
Hosting service settings (sorry they aren't in english)
The node server is running a reactjs frontend and this frontend makes requests to the server through the fetch api. The request URLs looks like this https://www.wordpress.com/node/api/user-login. In my react code I have this to create the request
res = await fetch("api/user-login/", {
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
method: "POST",
body,
})
I expected the server to POST, but instead I got this error message
404 Not Found
Cannot POST //api/user-login/
I don't know why the two slashes too
Request headers please note that the links painted in blue are equivalent to the wordpress.com/node example
My routes.js and my server.js files (on the backend side) look like this
server.js
app.use(express.static(path.join(__dirname, 'build')))
app.use("/api", require("./src/routes"))
app.get('/', function(_req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
})
src/routes.js
const routes = express.Router()
routes.post("/user-login", login)
routes.get("/refresh-token", refreshToken)
module.exports = routes
I don't know why I can't post to this route. They are in the same site, so I think CORS is not a problem.
Another important point is that the wordpress website is using the https protocol and I tried to solve the Cannot POST error setting the node server with and without https, but neither worked (I used the same certificate and key of the wordpress).
Any answer here are appreciated, thank you so much and I'm sorry for my bad English, once again thank you.
I changed this line in server.js and it worked, maybe it's a problem from the calling in the API, I don't know exactly why it was trying to POST to "//api" (with two slashes).
app.use("//api", require("./src/routes"))
Anyway, thank you all for helping

Is there a way to add a separate node website under a node website's route?

I have two Node.js websites (website_a, website_b) that use ExpressJS. I wanted to add "website_b" under a route of "website_a".
For example, going to http://www.website_a.com/website_b will show the pages of "website_b".
i.e. Requesting http://www.website_a.com/website_b/ shall not redirect the request to website_b (http://www.website_b.com/) but instead fetch the request from website_b and respond from the website_a server.
The response on requesting http://www.website_a.com/website_b/about shall be the same as requesting http://www.website_b.com/about.
⚠ The websites (website_a, website_b) are completely separate and shall stay separate.
Is there a way to use the route.use() to add route /website_b to website_a and let ExpressJS fetch the response from website_b and then respond the same from website_a's server.
Maybe the thing you want ask it to proxy pass certain routes to another websites. I've do before with one npm module http-proxy-middleware
npm i http-proxy-middleware
Proxy /api requests to http://www.example.org
var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
app.use(
'/api',
proxy({ target: 'http://www.example.org', changeOrigin: true })
);
app.listen(3000);
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
So basically it will send request to another website under website one.
check out more about it - https://www.npmjs.com/package/http-proxy-middleware
Hope it helps :)

Proxy running node-react application

I just created a react-node-SQL app and I want it to run on Google Cloud (not firebase)
My React app runs on different port and my node app runs on different port.
I followed this article and added this line in my react-app package.json but I didn't worked out i.e href in button was still going to localhost:8081 but It didn't worked
I had my node running on port 8080, In package.json of my react app i added "proxy": "http://localhost:8080/" and in button when I did href="/api/status" it was going to localhost:8081 on which the react app was running
Now, Is it possible to run both node and react under the same project? or we need to create separate project for them.
[Update:] I am using webpack, In my webpack config file, I added this
devServer: {
proxy: {
'/': 'http://localhost:8080'
}
},
The problem with this, that even in my react app, on Startup (running on 8081) when it opens the webpage localhost:8081/ it throws an error saying cannot get the page
but if I do something like this
devServer: {
proxy: {
'/api': 'http://localhost:8080'
}
},
it opens the page homepage normally. Now my api and callback uRL after authentication aren't configured with have prefix as api.
Basically, when you do an ajax request from react app, like axios or fetch it will use the proxy: <..> for the backend url. But, href doesn't work with proxies. In that case you need to manually configure proxy using the setupProxy.js documented in the manual proxy page.
Check out this issue:
Same error here, it still routes to localhost:3000/api/auth/google, my
CRA version is 2.1.3 It seems http-proxy-middleware is the only
working way. I have to Configuring the Proxy Manually
From the react doc:
If the proxy option is not flexible enough for you, you can get direct
access to the Express app instance and hook up your own proxy
middleware.
You can use this feature in conjunction with the proxy property in
package.json, but it is recommended you consolidate all of your logic
into src/setupProxy.js.

Resources