I'm trying to setup a proxy for webpack-dev-server using multiple domains. Our system works like this:
- login.domain.ext
- project.domain.ext
now project runs on webpack dev server, whilst login is a PHP backend and that works on a dev machine.
I managed to set up a proxy config to redirect to log in on SSL and trap all return redirects so that I can re-add port 8080.
However webpack seems to ignore the domain, and now just acts like it's proxying everything to the login project.
Setting disableHostCheck to false gives an error with the login domain nog being a valid host.
I can't find anything on hostname proxy all configs I see are about path proxying. But I can't imagine being the only one with a setup like this.
Here's the dev server config
import { configPath } from "../vars/paths.config";
const webpackMerge = require('webpack-merge');
const webpack = require('webpack');
import { commonConfig } from './common.config';
const fs = require('fs');
export let developmentConfig;
developmentConfig = {
devServer: {
historyApiFallback: true,
public : 'project.domain.ext.dev1:8080',
disableHostCheck: true,
https: {
key: fs.readFileSync( configPath + '/resources/ssl/san_domain_com.key' ),
cert: fs.readFileSync( configPath + '/resources/ssl/san_domain_com.crt-extensions' )
},
stats: {
colors: true
},
proxy: {
"https://login.domain.ext.dev1:8080/": {
target: "https://login.domain.ext.dev01",
secure: false,
changeOrigin: true,
onProxyReq: relayRequestHeaders,
onProxyRes: relayResponseHeaders
}
},
hot: true,
open: true,
progress: true
},
plugins : [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin()
]
};
developmentConfig = webpackMerge( commonConfig, developmentConfig );
function relayRequestHeaders(proxyReq, req) {}
function relayResponseHeaders(proxyRes, req, res) {
if (proxyRes.headers && proxyRes.headers.location) {
let expression = new RegExp('https://(project\\.(domain\\.ext|alt-domani\\.ext)\\.dev1)/', 'i');
let match = proxyRes.headers.location.match( expression );
if (match) {
proxyRes.headers.location = proxyRes.headers.location.replace(match[1], match[1] + ':8080');
res.append( 'location', proxyRes.headers.location );
}
}
}
1 Answer 1
I figured it out, you can do this using the
- router for routing domains
- onProxyRes for changing response redirect headers
- the bypass section for '.htaccess' style everything to index.html
This is my final proxy config
/**
* Proxy guide at:
* https://github.com/chimurai/http-proxy-middleware
* https://github.com/chimurai/http-proxy-middleware/tree/master/recipes
*/
const domains = [
'domain.ext',
'domain2.ext'
];
const domainPrefixes = [
'api',
'admin',
'login'
];
let routedRoutes = {};
domains.map( function( domain ) {
domainPrefixes.map( function( prefix ) {
routedRoutes[ prefix + '.' + domain + ':8080' ] = 'https://' + prefix + '.' + domain + ':443'
} )
} );
export const devServerProxyConfig = {
devServer: {
disableHostCheck: true,
proxy: {
"/api/": {
target: "https://api.domain.ext/",
secure: false,
changeOrigin: true,
pathRewrite: {
'/api': ''
}
},
"https://interface.domain.ext:8080": {
target: "https://interface.domain.ext:8080",
secure: false,
changeOrigin: true,
bypass: bypassFunction,
onProxyReq: relayRequestHeaders,
onProxyRes: relayResponseHeaders,
router: routedRoutes
},
}
}
};
/**
* Proxy bypass function to bypass request to interface.domain.ext back to /index.html
*
* @param req
* @param res
* @param proxyOptions
* @returns {string}
*/
function bypassFunction(req, res, proxyOptions) {
if (req.headers && req.headers.host) {
let expression = new RegExp('(my\\.(' + domains.join('|').replace(new RegExp('\\.', 'gi'), '\\.') + '))', 'i');
let match = req.headers.host.match( expression );
if (match && match.length > 0) {
return '/index.html';
}
}
}
/**
* Adjust request headers before send to script
* @param proxyReq
* @param req
*/
function relayRequestHeaders(proxyReq, req) {}
/**
* Adjust response headers before send to browser
* @param proxyRes
* @param req
* @param res
*/
function relayResponseHeaders(proxyRes, req, res) {
if (proxyRes.headers && proxyRes.headers.location) {
// my is not in the prefixes
let expression = new RegExp('https://(((my|' + domainPrefixes.join('|') + ')\\.(' + domains.join('|').replace(new RegExp('\\.', 'gi'), '\\.') + '))(:443)?)/', 'i');
let match = proxyRes.headers.location.match( expression );
if (match && match.length > 0) {
// match[0] is full url
// match[1] is url including port (if set)
// match[2] is url excluding port
// match[3] is domain prefix
// match[4] is domain
// match[5] is port if set
proxyRes.headers.location = proxyRes.headers.location.replace(match[1], match[2] + ':8080');
res.append( 'location', proxyRes.headers.location );
}
}
}