webpack-dev-server set cookie via proxy - reactjs

We have setup our development environment with webpack-dev-server. We use its proxy config to communicate with the backend.
We have a common login page in the server which we use in all our applications. We it is called, it sets a session cookie which expected to passed with subsequent requests. We have used the following config but the cookie is not set in the browser for some reason. I can see it in response header in the network tab of dev tool.
const config = {
devServer: {
index: "/",
proxy: {
"/rest_end_point/page": {
target: "https://middleware_server",
secure : false
},
"/": {
target: "https://middleware_server/app/login",
secure : false
},
}
The https://middleware_server/app/login endpoint returns the login page with the set-cookie header.
The proxy is used to avoid CORS errors when accessing login pages and API calls.
Upto this point no code from the application is executed. Do we have to do something in the coomon login page to get the cookie set?
the application is written with React.
Any help would be appreciated.

I have the same use case and this is what I have done.
In my case, I have multiple proxy targets so I have configured the JSON (ProxySession.json) accordingly.
Note: This approach is not dynamic. you need to get JSESSIONID manually(session ID) for the proxy the request.
login into an application where you want your application to proxy.
Get the JSESSIONID and add it in JSON file or replace directly in onProxyReq function and then run your dev server.
Example:
Webpack-dev.js
// Webpack-dev.js
const ProxySession = require("./ProxySession");
config = {
output: {..........},
plugins: [.......],
resolve: {......},
module: {
rules: [......]
},
devServer: {
port: 8088,
host: "0.0.0.0",
disableHostCheck: true,
proxy: {
"/service/**": {
target: ProxySession.proxyTarget,
changeOrigin: true,
onProxyReq: function(proxyReq) {
proxyReq.setHeader("Cookie", "JSESSIONID=" + ProxySession[buildType].JSESSIONID + ";msa=" + ProxySession[buildType].msa + ";msa_rmc=" + ProxySession[buildType].msa_rmc + ";msa_rmc_disabled=" + ProxySession[buildType].msa_rmc);
}
},
"/j_spring_security_check": {
target: ProxySession.proxyTarget,
changeOrigin: true
},
"/app_service/websock/**": {
target: ProxySession.proxyTarget,
changeOrigin: true,
onProxyReq: function(proxyReq) {
proxyReq.setHeader("Cookie", "JSESSIONID=" + ProxySession[buildType].JSESSIONID + ";msa=" + ProxySession[buildType].msa + ";msa_rmc=" + ProxySession[buildType].msa_rmc + ";msa_rmc_disabled=" + ProxySession[buildType].msa_rmc);
}
}
}
}
ProxySession.json
//ProxySession.json
{
"proxyTarget": "https://t.novare.me/",
"build-type-1": {
"JSESSIONID": "....",
"msa": "....",
"msa_rmc": ...."
},
"build-type-2": {
"JSESSIONID": ".....",
"msa": ".....",
"msa_rmc":"....."
}
}

I met the exact same issue, and fixed it by this way:
This is verified and worked, but it's not dynamic.
proxy: {
'/my-bff': {
target: 'https://my.domain.com/my-bff',
changeOrigin: true,
pathRewrite: { '^/my-bff': '' },
withCredentials: true,
headers: { Cookie: 'myToken=jx42NAQSFRwXJjyQLoax_sw7h1SdYGXog-gZL9bjFU7' },
},
},
To make it dynamic way, you should proxy to the login target, and append a onProxyRes to relay the cookies, something like: (not verified yet)
onProxyRes: (proxyRes: any, req: any, res: any) => {
Object.keys(proxyRes.headers).forEach(key => {
res.append(key, proxyRes.headers[key]);
});
},

"/api/**": {
...
cookieDomainRewrite: { "someDomain.com": "localhost" },
withCredentials: true,
...
}

You can use this plugin to securely manage auth cookies for webpack-dev-server:
A typical workflow would be:
Configure a proxy to the production service
Login on the production site, copy authenticated cookies to the local dev server
The plugin automatically saves your cookie to system keychain

https://github.com/chimurai/http-proxy-middleware#http-proxy-options
use option.cookieDomainRewrite and option.cookiePathRewrite now

cookies ??
devServer: {
https: true, < ------------ on cookies
host: "127.0.0.1",
port: 9090,
proxy: {
"/s": {
target: "https://xx < --- https
secure: false,
//pathRewrite: { "^/s": "/s" },
changeOrigin: true,
withCredentials: true
}
}
}
. . . . . . . . . . .

Related

Webpack#5 output.libraryTarget='system' breaks app

I have an old application and i have micro-frontend structure there. The application was using react-scripts#4 and this version had several vulnerabilities so i decided to upgrade it. While react-scripts#5 is not compatible with webpack#4, i needed to upgrade it too. However, I cannot use output.libraryTarget='system' or output.library.type='system' anymore. If i remove this part then app works but i cannot access micro-frontends. Here is my craco.config file;
import {
BabelOptions,
DevServerOptions,
EsLintOptions,
WebpackOptions,
} from '#craco/craco';
export default {
babel: {
plugins: [['#babel/plugin-proposal-decorators', { legacy: true }]],
} as BabelOptions,
eslint: {
enable: false,
} as EsLintOptions,
webpack: {
configure: (webpackConfig) => {
// use system
webpackConfig.output.libraryTarget = 'system';
delete webpackConfig.optimization;
// adding externals
webpackConfig.externals = [
'#test-app/mf-example',
];
return webpackConfig;
},
} as WebpackOptions,
// Adding Server
devServer: ((devServerConfig) => {
// devServerConfig.injectClient = false;
devServerConfig.proxy = {
...devServerConfig.proxy,
'/mf-example': {
target: process.env.MF_EXAMPLE,
secure: false,
changeOrigin: true,
}
};
return devServerConfig;
}) as DevServerOptions,
};
Btw, the problem is not related to other files or configs so i did not share them.

Websockets, truffle, ganache and react setup issues connection not open on send()

Sometimes I refresh, and it works. Sometimes it just doesn't work.
I tried changing ganache GUI settings to use port 8545 which I read is the WebSockets port but it still won't connect. ws:127.0.0.1 won't work and neither will http://
This is my truffle config file. The rest of the code is large and won't help much.
// See <http://truffleframework.com/docs/advanced/configuration>
// #truffle/hdwallet-provider
// var HDWalletProvider = require("truffle-hdwallet-provider");
const path = require("path");
var HDWalletProvider = require("#truffle/hdwallet-provider");
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
// contracts_directory: "./allMyStuff/someStuff/theContractFolder",
contracts_build_directory: path.join(__dirname, "/_truffle/build/contracts"),
// migrations_directory: "./allMyStuff/someStuff/theMigrationsFolder",
networks: {
ganache: {
host: "127.0.0.1",
port: 7545,
//port: 8545,
network_id: 5777,
//network_id: "*", // Match any network id,
websockets: false, // websockets true breaks TODO: connection not open on send()
// wss
},
},
};
This is some of my code on the actual screen in question.
const options = {
web3: {
block: false,
fallback: {
type: 'ws',
//url: 'ws://127.0.0.1:8546',
url: 'http://127.0.0.1:7545',
},
},
contracts: [MyStringStore],
// polls: {
// accounts: IntervalInMilliseconds,
// },
events: {},
};
I don't understand why sometimes it works and I can see drizzle state and sometimes I can't. React native and web3 is very new to me.
I get errors like this:
00:06 Contract MyStringStore not found on network ID: undefined
Error fetching accounts:
00:06 connection not open
I am having real difficulty setting up drizzle as well. One thing I see is that your
url: 'http://127.0.0.1:7545',
For some reason Drizzle only works with 'ws' as the prefix for such a URL. I am trying to follow this guide by people who got it working.
I think websocket is only available in the command line version.
Try install and use ganache-cli instead of the gui version.

Using constant/variable as webpack dev server proxy URL pattern

In our development server setup we use webpack-dev-server proxy setting to connect ot the APIs via middleware server. Time to time we have to change the middleware server settings and without changing the information in multiple places we would like to keep them in a single place.
Therefore we tried the following,
const MIDDLEWARE_SERVER = 'https://midlleware.server';
const MIDDLEWARE_RESOURCE = '/xyz';
const MIDDLEWARE_API_ENDPOINT = MIDDLEWARE_SERVER + MIDDLEWARE_RESOURCE + '/api';
devserver: {
proxy: {
MIDDLEWARE_RESOURCE : {
target: MIDDLEWARE_API_ENDPOINT;
pathRewrite: { MIDDLEWARE_RESOURCE: '' },
}
}
This doesn't work resulting with a 404 error because the URL pattern has not recognised (we checked by catching a onProxyReq event).
But if we replace the MIDDLEWARE_RESOURCE with '/xyz' in the proxy section it works.
it that a limitation in providing 'proxy' patterns?
Thanks
I was able to get it work by using [MIDDLEWARE_RESOURCE] notation. Like below
const MIDDLEWARE_SERVER = 'https://midlleware.server';
const MIDDLEWARE_RESOURCE = '/xyz';
const MIDDLEWARE_API_ENDPOINT = MIDDLEWARE_SERVER + MIDDLEWARE_RESOURCE + '/api';
devserver: {
proxy: {
[MIDDLEWARE_RESOURCE] : {
target: MIDDLEWARE_API_ENDPOINT;
pathRewrite: { MIDDLEWARE_RESOURCE: '' },
}
}

How to proxy with Gatsby and custom Webpack config (netlify-lambda)

I'm using Gatsby with netlify-lambda which creates a server for functions on the 9000 ports:
http://localhost:9000/myFunctionName
In production the address of the functions is:
/.netlify/functions/myFunctionName
So I would like to have a dev mode proxy that serves http://localhost:9000/ when I call /.netlify/functions.
My custom Webpack config in gatsby-node.js:
exports.modifyWebpackConfig = ({ config, stage }) => {
if (stage === 'develop') {
config.merge({
devServer: {
proxy: {
'/.netlify/functions': {
target: 'http://localhost:9000',
pathRewrite: {
'^/\\.netlify/functions': ''
}
}
}
}
})
}
}
Does not work.
I tried this too https://www.gatsbyjs.org/docs/api-proxy/#api-proxy but I need to rewrite the url and not just prefix.
What's the best way to use netlify-lambda with Gatsby ?
Thanks
Update: Gatsby now does support Express middleware, in this merged PR. This will not support the Webpack Dev Server proxy configuration, but will allow using ordinary Express proxy middleware.
To use with netlify-lambda just add this to your gatsby-config.js :
const proxy = require("http-proxy-middleware")
module.exports = {
developMiddleware: app => {
app.use(
"/.netlify/functions/",
proxy({
target: "http://localhost:9000",
pathRewrite: {
"/.netlify/functions/": "",
}
})
)
}
}
https://www.gatsbyjs.org/docs/api-proxy/#advanced-proxying
Unfortunately, the Gatsby development proxy configuration is not at all extensible. Since Gatsby does not use the webpack dev server, its proxy options are not available. See https://github.com/gatsbyjs/gatsby/issues/2869#issuecomment-378935446
I achieve this use case by putting an nginx proxy in front of both my Gatsby development server and the netlify-lambda server. This is a very simplified version of the proxy server config (trailing slash is important):
server {
listen 8001;
location /.netlify/functions {
proxy_pass http://0.0.0.0:9000/;
}
location / {
proxy_pass http://0.0.0.0:8000;
}
}
I'm using an nginx proxy anyhow, so that's not an undesirable amount of extra dev setup, but it would certainly be better if Gatsby supported this common case.

How to set file's default suffix in webpack-dev-server?

I use webpack-dev-server to server my project.Here is the question, When the browser send a request like http://localhost:9000/test/menuList, acutally I want it to find http://localhost:9000/test/menuList.json. How should I do?
You can try tweaking Webpack-dev-server proxy object pathRewrite property
devServer: {
contentBase: <Your-Value>,
proxy = {
'/test/menuList': {
target: http://localhost:9000/test/menuList,
pathRewrite(req, options) {
return req + '.json';
}
}
}
...
}

Resources