Skip to content

Commit

Permalink
STCLI-247 improve proxying by overwriting CORS headers, static alias …
Browse files Browse the repository at this point in the history
…for localhost (#351)

There are two features here:

1. provide new CLI option `--proxyUrl` to allow use of a hostname other than
   localhost, allowing the machine hosting the bundle to be accessed
   remotely (e.g. from a conference room, or by a colleague in another
   office, etc etc)
2. overwrite CORS headers between the proxy and browser, satisfying the
   browser that CORS requirements are being met (shhhhh)

Details on Part 2:

Overwrite the following CORS headers between the proxy and browser:
```
Access-Control-Allow-Origin: http://localhost:${PORT}
Access-Control-Allow-Credentials: true
```
The ACAO value is commonly set to `*` for un-credentialed requests (i.e.
those without cookies), but as MDN docs for CORS notes:

> When responding to a credentialed requests request, the server must
> specify an origin in the value of the `Access-Control-Allow-Origin`
> header, instead of specifying the “*” wildcard. Likewise, the ACAC value
> is commonly set to `""` for uncredentialed requests, but must be set to
> `true` to allow cookies to pass through.

(from https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)

These CORS settings appear to have been in place before RTR was
introduced, and may still be in place in some backend environments.
Overriding these values in the local proxy is a prudent way to allow
local development to continue while waiting for the backend settings to
catch up.

Refs STCLI-247

---------

Co-authored-by: Kevin Day <[email protected]>
  • Loading branch information
zburke and kaladay authored Sep 16, 2024
1 parent 48e31cc commit 272de3e
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 6 deletions.
3 changes: 2 additions & 1 deletion doc/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,7 @@ Option | Description | Type | Notes
`--stripesConfig` | Stripes config JSON | string | supports stdin
`--tenant` | Specify a tenant ID | string |
`--startProxy` | Start a local proxy server between the platform and okapi | boolean | default: false
`--proxyHost` | Scheme and host name for the proxy server | string | default: http://localhost
`--proxyPort` | Port number for the proxy server | number | default: 3010

Examples:
Expand All @@ -1150,7 +1151,7 @@ $ stripes serve --existing-build output
```
Serve a platform with a local proxy server that points to a remote okapi server:
```
$ stripes serve --startProxy --proxyPort 3010 --okapi http://some-okapi-server.folio.org
$ stripes serve --startProxy --proxyHost http://localhost --proxyPort 3010 --okapi http://some-okapi-server.folio.org
```
Serve an app (in app context) with a mock backend server":
```
Expand Down
6 changes: 6 additions & 0 deletions lib/commands/common-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ module.exports.serverOptions = {
default: false,
group: 'Server Options:',
},
proxyHost: {
type: 'string',
describe: 'Proxy scheme and host',
default: 'http://localhost',
group: 'Server Options:',
},
proxyPort: {
type: 'number',
describe: 'Proxy server port',
Expand Down
7 changes: 3 additions & 4 deletions lib/commands/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ const serveBuildOptions = Object.assign({}, buildOptions);
delete serveBuildOptions.publicPath;

function replaceArgvOkapiWithProxyURL(argv) {
const proxyURL = `http://localhost:${argv.proxyPort}`;
argv.okapi = proxyURL;
argv.okapi = `${argv.proxyHost}:${argv.proxyPort}`;

if (argv.stripesConfig?.okapi) {
argv.stripesConfig.okapi.url = proxyURL;
argv.stripesConfig.okapi.url = argv.okapi;
}
}

Expand Down Expand Up @@ -52,7 +51,7 @@ function serveCommand(argv) {

if (argv.startProxy) {
console.info('starting proxy');
childProcess.fork(path.resolve(context.cliRoot, './lib/run-proxy.js'), [argv.okapi, argv.proxyPort]);
childProcess.fork(path.resolve(context.cliRoot, './lib/run-proxy.js'), [argv.okapi, argv.port, argv.proxyHost, argv.proxyPort]);
// if we're using a proxy server - we need to pass the proxy host as okapi to Stripes platform
replaceArgvOkapiWithProxyURL(argv);
}
Expand Down
10 changes: 9 additions & 1 deletion lib/run-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ const app = express();

const OKAPI = process.argv[2];
const PORT = process.argv[3];
const PROXY_HOST = process.argv[4];
const PROXY_PORT = process.argv[5];

app.use(
'/',
createProxyMiddleware({
target: OKAPI,
changeOrigin: true,
on: {
proxyRes: (proxyRes) => {
proxyRes.headers['Access-Control-Allow-Origin'] = `${PROXY_HOST}:${PORT}`;
proxyRes.headers['Access-Control-Allow-Credentials'] = 'true';
},
},
}),
);

app.listen(PORT);
app.listen(PROXY_PORT);

0 comments on commit 272de3e

Please sign in to comment.