webpack config : How do I add a request header when directing requests to proxy server? - webpack-dev-server

I am working on a react app, where while development we need to direct some requests to a backend server. I have added devServer.proxy option for that in webpack.config.js file -
config.devServer.proxy = {
"/apiV2": {
target: "https://beserveraddress:8080",
changeOrigin: true,
secure: false,
}
}
However I need to add custom cookie header value when redirecting to this backend server.
I have tried headers option but not able to get result. How can I add 'Cookie' header to the request before it is directed to backend proxy server?

Related

http proxy middleware is not created proxies in my react app

I am implementing http proxy middleware in to my react app. I want to proxing qa or dev backend services urls from my local .
Example of my dev login url below
https://cors-anywhere.herokuapp.com/https://dev.sju.uk/auth/login
my setupProxy.js
module.exports = function (app) {
app.use('/auth/login' ,createProxyMiddleware({
target: 'https://cors-anywhere.herokuapp.com/https://dev.sju.uk/auth/login',
changeOrigin: true,
})
);
};
I started my app and click the login button and the request got failed with 404 not found error . Not sure why my target is not replacing with my actual http://localhost:9009/auth/login uri to https://cors-anywhere.herokuapp.com/https://dev.sju.uk/auth/login.
Also am not getting proxy created message in my console when we do npm start as well. I am using webpack dev server not react-scripts . If any changes required on webpack side or am i missing anything badly please let me know. I tried small poc it got worked but that is simple without herokuapp things.
It took me some time to understand how the http-proxy-middleware works.
Look at the following diagram from the http-proxy-middleware Docs
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
For simple configurations, any request that your front-end does calling an API get observed by a matching pattern on the path section of the above diagram and overwritten with your target configuration, to be exposed in the header of the request as a different URL. This also help you in the development phase locally to avoid the CORS blocking mechanism of the browsers.
Example:
Let's imagine we need to call from our front-end exposed at http://localhost:3000 to an endpoint located at https://localhost:7005/api/WeatherForecast
This type of calls will be blocked in all browsers by CORS.
So, with the following config, you will be able to bypass the cors problem.
const { createProxyMiddleware } = require('http-proxy-middleware');
const context = [
"/api",
];
module.exports = function (app) {
const webApiProxy = createProxyMiddleware(context[0], {
target: 'https://localhost:7005',
secure: false,
changeOrigin: true,
headers: {
Connection: 'Keep-Alive'
},
logLevel: 'debug'
});
app.use(webApiProxy);
};
With this, any request made from http://localhost:3000 will be intercepted by the proxy-middleware and if it finds a /api in some part of the path will be changed to https://localhost:7005/api and also concatenate the rest of your original path following the /api.
So finally, your front-end will be asking things from http://localhost:3000 but all the request will arrive to https://localhost:7005 as if they were request by https://localhost:7005 and this will fix the Cors problem coz your requesting and responding from the same origin.
I Guess your can fix your problem by writting your config this way:
module.exports = function (app) {
app.use('/auth/login' ,createProxyMiddleware({
target: 'https://dev.sju.uk/auth/login',
changeOrigin: true,
headers: {
Connection: 'Keep-Alive'
},
})
);
};
Bare in mind, this libray not only can help you with the CORS problem but also to perform hundred of things for any request/response like change arguments from the body, add things to the body, add headers, perform operations before the request aka logging what's requested, perform operations on the response aka logging again what has returned, etc, etc.
Hope this will help to resolve your issue!

ReactJS/Next.js: CRA Proxy Does Not Work With Next.js (Attempting To Route API Request To Express server)

I'm currently upgrading a vanilla React app to use Next.js (version 7.0.0). The app was originally built with Create-React-App and utilizes the proxy built in to CRA's server.
In development my React app runs on port 3000 and I have an Express server running on port 5000. Prior to adding Next.js I'd been using a proxy object within the package.json file to route API requests to the server.
API request:
const res = await axios.get('/api/request')
Proxy object in package.json:
"proxy": {
"/api/*": {
"target": "http://localhost:5000"
}
}
This had been working great, but with Next.js I'm now getting an error:
GET http://localhost:3000/api/request 404 (Not Found)
^ This is supposed to be pointing to locahost:5000 (my server)
Does anyone know how I might be able to route API requests from a React/Next.js client to an Express server running on a different port?
OK, so I've figured this out. You can create a Node.js proxy for Express by using http-proxy-middleware
You can then configure the target option to proxy requests to the correct domain:
const proxy = require('http-proxy-middleware')
app.use('/api', proxy({ target: 'http://localhost:5000', changeOrigin: true }));

Webpack dev server with proxy does not handle redirects

I am developing a react application. For development I am using webpack dev server. My backend application is a spring boot. When I make a request and I am not authenticated the backend redirects me to the login page (localhost:8080/login).
My webpack dev server runs on port 3000. All my api call are redirected to the backend using a proxy from the devserver.
devServer: {
historyApiFallback: true,
contentBase: './',
proxy: [{
context: ["/api"],
target: "http://localhost:9090"
}],
changeOrigin: true,
secure: false
When I access a protected resource and I am not authenticated, for example localhost:3000/api/test, I am redirected to localhost:8080/login and I can see 2 request: a 302 request and a 200 request to /login. The problem is that the dev server does not actually do the redirect and does not show the login page. When serving the content from my spring boot application the redirect is done.
Is this a problem related to webpack dev server or is there something wrong in my understanding of the proxy mechanism?

React app using API with another origin (CORS)

I have a react app, which uses a java ee backend rest server, running on another domain. I have enabled CORS:
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Headers : origin, content-type, accept, authorization
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Max-Age : 1209600
I am using react with fetch like this:
export function get(path, headers) {
return fetch(apiUrl + path, {
"metod" : "GET",
"headers" : headers,
"credentials" : "include"
})
}
My react app is running on http://localhost:3000.
When I am logging in, the server returns the Set-Cookie, but the cookie is not included in any further request to the server, unless I try to log in again. Then it is included for that specific login request.
Any suggestions?
I just want to share how I make my local development painless by this post if you are using create-react-app by just adding your main API url proxy to your package.js for example "proxy": "http://localhost:8080/API"
No need to setup CORS on your backend.
Install this.
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=es
Once installed, click on his BrowserIcon and toggle on. It is all. You will not receive more error.
EDIT. Solution for Production
If you want config it from your server (or simply not adding a browser extension, try this:)
If you are using node.js do the following: node.js server file: response.writeHead(200, { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' })
fetch('http://ajax.googleapis.com/ajax/services/feed/load?v=‌​1.0&num=8&q=http://r‌​ss.cnn.com/rss/editi‌​on_entertainment.rss‌​?output=rss', { method: 'get', mode: 'no-cors', }).then(() => { console.log('Works!'); });
Other solution:If you are using PHP too you can add: <?php header('Access-Control-Allow-Origin: *'); ?> into your PHP File. As I see, it is not the case, so... In your server (eg: Apache) add this directive: Header set Access-Control-Allow-Origin * in Settings (as the first option).
So, I solved the problem by using another stackoverflow thread and robertklep's comment. As stated here: "When working on localhost, the cookie domain must be omitted entirely.". I implemented robertkleps idea, but did not set the domain. It resulted in a Set-Cookie like this: Set-Cookie:kek=7fukucsuji1n1ddcntc0ri4vi; Version=1; Path=/; Max-Age=100000. This works fine.
To add more on existing answers.
With react you can use "proxy" in your package.json to avoid CORS.
Basically if you need to reach localhost:8100 (your java backend) and your react app run on localhost:3000
You can set:
In your package.json
"proxy": "http://localhost:8100"
And then when you want to make a get to /hello which would be an endpoint of your java API you can do:
import axios from 'axios';
axios.get('/hello')
.then(resp => {
console.log(resp.data);
});
And it will be redirected to http://localhost:3000/hello so you will avoid CORS.

Webpack not accepting POST requests

I'm currently working on an Angular 2 web application which communicates with an API. In the application the user is able to choose a payment option and the API will return the url to the payment service.
The problem is that the payment service uses POST to go to the confirmation page which WebPack does not accept (for some reason it only allows GET requests) and we get the following error:
Cannot POST /selection/payment-method
Does anybody know how we could configure that WebPack allows POST requests also? I've contacted the payment provider but it is not possible to do a GET request instead of POST.
Thanks
Based on #Sven's answer, modification to the setup so that it works for POST all throughout
Add dependencies on body-parser, sync-request and add require dependencies on both in your webpack.config.js
var bodyParser = require('body-parser');
var request = require('sync-request');
In devServer part of webpack.config.js
devServer: {
setup: function(app) {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post(/^\/(URL1|URL2|URL3)\//, function(req, res) {
var serviceCallResponse = request('POST', 'your app server url here' + req.originalUrl, {
json:req.body
});
res.send(serviceCallResponse.getBody('utf8'));
});
},
proxy: {
'*/other URLs proxy/*': 'your app server url here'
}
}
Change URL1/2 to the URLs you want to proxy and you place your app servers address.
This will work for all sorts of POST request proxy (working on json payload)
A hackish way to at least not get 404 errors is to proxy requests to /selection/payment-method and send back an empty response (or whatever content you want, I think that res is an instance of Express's Response class) for those, by adding the following to webpack.config.js:
devServer: {
proxy: {
'/selection/payment-method': {
bypass : (req, res) => res.end()
}
}
}
Documentation here.
Thanks to #robertklep who send me the link to the proxy documentation we found a way to deal with it. What we needed to do was instead of handling the POST request we needed to transform it someway into a GET. After reading some more of the documentation we came across the setup: property for your webpack-dev-server configuration.
With the setup: property you get the expressjs object and you are able to catch urls before it hits the route that says Cannot POST /url/to/page.
We ended up with this:
devServer: {
setup: function(app) {
app.post('/selection/payment-method', function(req, res) {
res.redirect('/selection/payment-method');
});
},
}
This way we got a GET request instead of POST and our application does an API request to check if the payment succeeded or not.
This is only used in development!
The Webpack-dev-server is only intended as your front-end server only, eg. to serve your static assets. Therefore only GET requests are supported.
If you would want to use a proxy or backend server, then you should implement this. You can use Express for this.
See how you can setup basic routing.

Resources