5

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 );
 }
 }
}
asked Dec 12, 2017 at 9:22

1 Answer 1

4

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 );
 }
 }
}
answered Dec 12, 2017 at 10:25
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.