How Do I Proxy Requests for Rsocket on React app - reactjs

I need to proxy both rsocket and http in react app. I was successful adding proxy to http request by adding to package json
"proxy": "http://192.184.24.12:82"
How do I do it to rsocket that sits on top of websocket.
Need to work http and rsocket simultaneously
let client = new RSocketClient({
transport: new RSocketWebSocketClient(
{
url: "ws://localhost:7000/ws",
wsCreator: (url) => new WebSocket(url),
debug: true,
},
BufferEncoders
),
setup: {
dataMimeType: "application/json",
metadataMimeType: MESSAGE_RSOCKET_COMPOSITE_METADATA.string,
keepAlive: 5000,
lifetime: 60000,
},
});

If you use rsocket in browser - then you use a websocket transport underneath. That said, if your proxy can proxy websocket (and I bet it can) you can proxy rsocket

Related

React axios - calling a http endpoint from https webapp

am trying to call a http endpoint from my react web application created using create react app
i am given the below code and a local pem file
caCrt = fs.readFileSync('./ca-crt.pem')
const httpsAgent = new https.Agent({ ca: caCrt , keepAlive: false })
axios.get(url, { params: params, httpsAgent: httpsAgent {color:#0747a6}}) .then( res =>
not sure how i can call it properly from frontend (https web app), i received several "mixed content" error from chrome, understand that i may not be able to use "fs" module from my react app

React Client Cors issue

I am learning react, I currently have a .net core API running in visual studio on localhost:7071.
The Local API is not running cors as there is no requirement for it to use Cors.
Creating a simple react client using the following will not return data due to a cors error?
I have tried a number of solutions online and none of them work, so how can I make this "simple" react client work without generating the following error
Access to XMLHttpRequest at 'http://localhost:7071/api/Users' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
function GetApiResults(){
const axios = require('axios').default;
axios.defaults.headers.common["Access-Control-Allow-Origin"] = "*";
axios({
method: 'get',
headers: { 'Content-Type': 'application/json' },
url: 'http://localhost:7071/api/Users',
}).then(function (response) {
console.log(response.data);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}
export default GetResults;
You have a pretty straighforward description of the issue, browser expects the external resouces you are using (API in your case, external in terms it is not on same port) to provide CORS headers. If they are not set - browser will not execute the request. It will execute the request if you open the resource URL in browser tab, but if you are on localhost:3000 - any requests initiated by this page to anything that is not on localhost:3000 will require CORS to be set.
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0
Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction is called the same-origin policy. The same-origin policy prevents a malicious site from reading sensitive data from another site.
So either enable CORS support in your backend, either use CRA feature called Proxy: https://create-react-app.dev/docs/proxying-api-requests-in-development/
I prefer the manual proxy configuration, at the very end of the article.
Important: this proxy is for DEVELOPMENT only!
Here is a step-by-step instruction, just tested:
Install npm install http-proxy-middleware --save
Add src/setupProxy.js with content:
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
// I have a different port and Visual Studio might randomly change it
// Fix: edit running configuration
// https://stackoverflow.com/questions/70332897/how-to-change-default-port-no-of-my-net-core-6-api
// Notice: no /api at the end of URL, it will be added.
// more details at: https://www.npmjs.com/package/http-proxy-middleware
target: "https://localhost:7002",
changeOrigin: true,
// Im using .net core 6 starting api template
// which is running with a self-signed ssl cert with https enabled
secure: false
})
);
};
Modify your AXIOS configuration object to use new URL:
function GetApiResults() {
const axios = require("axios").default;
axios({
method: "get",
headers: { "Content-Type": "application/json" },
url: "/api/WeatherForecast"
})
/* ... */
}
Note: Im using default web api project, only changed [Route("api/[controller]")] (added api/) for Controller.
Restart the app and watch for logs from npm start output, proxy can log some errors there.
CORS is a browser feature. So, the browser you are using to access the React app must require you to use CORS. You need to setup CORS on your backend and allow connections from remote origin.
It will be good if you add CORS enabling code on Server Side. if your server-side app is in Express JS then add below middleware-
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "http://localhost:3000"); or add your react app url.
next();
});

My react app and express server are on different ports

Problem/error:
I am running my react app on port 3000 and express on 3001.
error: Access to fetch at 'http://localhost:3001/api' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
//react code
//this function gets called when a button get pressed
...
post = () => {
const client_data = {info: this.state.input};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json
},
body: JSON.stringify(client_data)
}
fetch("http://localhost:3001/api", options);
}
...
Server is pretty simple
var express = require('express');
var app = express();
app.post('api', (request, response)=>{console.log(request})
(when I add "app.listen(3000)" react stops working)
You have to proxy your requests from react to express. The best way is to let it do your WebPack devServer, having this configuration:
(I assume, your express server is on 3000 and your React app on 3001)
devServer: {
...
...
proxy: {
'/api': {
target: 'http://127.0.0.1:3000/',
},
},
This says, that whichever request to path /api will be redirected to port 3001. Then you fetch to
fetch("/api", options);
Client automatically requests localhost:3001 (port on which the application is running), but the proxy redirects to 3000.
Brief explanation:
When developing react app, react creates a live developing enviroment that runs on -p 3000. However, if I spin up a node backend on -p 3000, the ports collide and the live enviroment crashes.
Solution:
Spin the node backend on a different port (4000)
and make a proxy in the live app
SERVER:
app.listen(4000, () => console.log("server is up on -p 4000")
CLIENT:
In the react app package.json file insert this key/value:
{
...
"proxy": "http://localhost:4000",
...
}

Express CORs policy preventing Apollo client from fetching from server

I'm running a react dev server on http://localhost:3000 and an express server on http://localhost:8080 and am using an Apollo Client to query the server. To enable session data to be passed from client to server I have added the credentials: "include" parameter when initializing the Apollo Client.
I've added the following line in my express server (before the routes are defined) to configure cors:
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
However, when executing queries, the following error is thrown:
Access to fetch at 'http://localhost:8080/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Why is the header response showing up as *? Am I configuring CORs incorrectly or am I missing something else?
The problem I was running into here was that despite enabling CORS for express:
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
The GraphQL middleware was over-riding the setting. Make sure to pass the cors: false param as shown below if using an Apollo Server and associated middleware.
gqlServer.applyMiddleware({ app, path: "/graphql", cors: false });
This error is a CORS error generated by the browser. use npm install --save http-proxy-middleware in your front end and add setupProxy.js file in frontend/src/setupProxy.js
setupProxy.js
//run defferent ports for website and api server
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api/', { target: 'http://localhost:8080/' })); //make change as per your application (So you can access your data on http://localhost:8080/api/ )
};
Alternate solution
If you are using webpack dev server, here's another way to proxy requests without making changes on NodeJS. Adding this to package.json:
"proxy": "http://localhost:8080"
Should allow webpack to proxy requests made to http://localhost:3000 to http://localhost:8080.
But this would mean request will need to be made to http://localhost:3000 instead of http://localhost:8080.
Since you have credentials: true, you should include the credentials in your fetch call:
fetch(url, {
credentials: 'include'
})
or
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
This will send the request with the headers set to Access-Control-Allow-Credentials: true
without this, it will be rejected.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

Webpack react app proxying to express server. Returning the json response from the express server rather than react components

I have a react web app that uses express as the back end.
I have it set up so that it proxies the request urls on the react server port (9000), to the express server (3000). Problem is, when I type in the path /examplepath, it returns the json that the express app returns, rather than returning the component that renders from getting that response from the backend. I am getting the express response and looking at it rather than react getting the express response and looking at it and then rendering and showing me that render.
When I click this button, it renders the correct page because it uses this code
componentDidMount() {
axios.post('/', qs.stringify(this.state))
.then(res => {
if (res.data === "session") {
this.setState({session: true})
}
})
}
It will render the page correctly using react
But if I visit the route directly it renders the json response from the express backend.
Like this
When I want it to render like the correcly rendered one using react
devServer: {
port: 9000,
open: true,
proxy: {
'/': 'http://localhost:3000'
}
}
THIS ^ is my webpack.config.js
Try adding historyApiFallback: true to your webpack.config.js file (not sure if the proxy will mess with it -- if so, use express cors middleware on the backend instead):
devServer: {
host: 'localhost',
port: 9000,
quiet: true,
historyApiFallback: true,
},
Also, a more common port setup is: React app on 3000 and API/server on 5000.
In addition, make sure you clearly separate your front and back end routes. Try keeping your back end routes to /api/someurl, and adding that to your proxy (and AJAX requests):
proxy: {
'/api/*': 'http://localhost:3000/api/'
}
Then, all front-end requests will be:
axios.get('/api/someurl').then().catch()
which will resolve to http://localhost:3000/api/someurl. This way, there's no chance of blending the front and back end routes.
Personally, I'd recommend cors over a proxy, because the proxy has been known to cause random connection issues.

Resources