How to add custom http header to angular module federation remoteEntry.js load call?
Asked Answered
A

3

2

I have a host app and few micro front end apps all are angular 15. I've used "@angular-architects/module-federation": "^15.0.3". Everything works fine, except I could not intercept the http call which loads the remoteEntry.js files of the mfe apps.

All the mfe apps are deployed in the server, the server to fullfil the request I've to add my authorization token to the request. I tried serveral ways but could not intercept the call and add the token to it.

  1. Angulat http interceptors are not intercepting this call.
  2. Module federation did not give any option to add http request.

Any suggestion would be greatly appreciated.

Below is my routing, where I load the mfe

{
        path: 'config',
        loadChildren: () =>
          loadRemoteModule({
            remoteEntry: environment.configREmoteEntryURL,
            type: "module",
            exposedModule: './Module'
          })
            .then(m => m.AppModule)
},
Adis answered 2/4, 2023 at 12:28 Comment(3)
Actually this is a method loadRemoteModule so inside this method you could add the token in the header. But the problem is, once the initial remoteentry.js file got downloaded with authentication. The remoteentry.js file will further download one more js file from server, that I could not handle :(Adis
I have same use case. Did you find any solution?Goeger
No , waiting for any update from @manfred steyerAdis
R
4

You can use a service worker to intercept and manipulate all requests towards the cdn of the MFEs.

service-worer.js

let authToken = '';

// This event listeners listens to the requests towards the login
// endpoint and stores that authToken at the corresponding variable.
self.addEventListener('fetch', function (event) {
  if (event.request.url === 'https://auth-endpoint/login') {
    event.respondWith(
      fetch(event.request)
        .then(function (response) {
          var responseClone = response.clone();

          responseClone.json().then(function (data) {
            authToken = data.token;
          });

          return response;
        })
    );
  }
});

// This requests listens to the requests towards the MFEs' endpoint
// and adds the custom headers needed fot the authorization
self.addEventListener('fetch', function (event) {
  if (event.request.url.startsWith('https://remotes-endpoint/')) {
    let url = new URL(event.request.url);

    let headers = new Headers(event.request.headers);

    headers.set('Content-Type', 'application/javascript');
    headers.set('Authorization', authToken);

    let newRequest = new Request(url, {
      method: event.request.method,
      headers,
      mode: 'cors',
      credentials: 'same-origin',
      redirect: event.request.redirect
    });

    event.respondWith(fetch(newRequest));
  }
});

You will need to regitser your service worker at your bootstrap.js

...
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function () {
    navigator.serviceWorker.register('/service-worker.js')
      .then(function (registration) {
        console.log('Service Worker registration successful with scope: ', registration.scope);
      }, function (err) {
        console.log('Service Worker registration failed: ', err);
      });
  });
}

Add CopyPlugin at your webpack configuration

const CopyPlugin = require('copy-webpack-plugin');

const config = {
  ...
  plugins: [
    ...
    new CopyPlugin({
      patterns: [
        // adjust 'service-worker.js' if your file is somewhere else
        { from: 'service-worker.js', to: '' }, 
      ],
    }),
  ]
}

module.exports = config;

You will also most probably need to remove the remotes from your module-federation configuration, as long as the authToken doesn't exist on mount of the consumer app until the user logs in. So the requests of the remotes will fail on mount. To resolve this you will need to load your remotes using Dynamic Remote Containers. There is a full implementation of this approach in this repo.

Reflector answered 19/6, 2023 at 14:4 Comment(1)
This answer deserves more credit and likes. Spent a whole one week trying to make it work and this approach is the ONLY one that works, when literally everything out there claims that it is not possible. This is working! Can't thank you enough!Rout
P
0

I'm afraid this is currently not possible.

What's your use case?

Polecat answered 2/4, 2023 at 12:46 Comment(1)
All the mfe apps are behind Kong gateway. To pass through kong gateway, the request need Authorization token. Currently I've disabled the kong gateway authentication. Within one week I've to enable the kong authentication. Before we go live.Adis
G
0

The solution is smart, but it did not work for me outside the box and I would change a few things.

  1. Request params: mode: 'cors', credentials: 'same-origin', - that implies server is using some authorization for remoteEntry file + it SHOULD be supporting cors requests. So writing it like that will create an Options request before initiating the real request, which might not be allowed on your server. Actually, common GET request (without custom headers), SHOULD NOT require CORS being turned on. So just omit credentials, and change mode to : mode: "no-cors" Of course, there might be different setups which may require that kind of thing and if your static files are protected by token: you may need original answer.

  2. The cache control header being sent did not work for me, but there is a simple enhancement you can do : let url = new URL(event.request.url);

    url = ${url}?${Date.now()};

The step two will guearantee you are getting a new copy of your file, adding this random hash on each request which will prevent proweser from caching it.

        let url = new URL(event.request.url);
        url = `${url}?${Date.now()}`;

        const newRequest = new Request(url, {
            method: event.request.method,
            headers: event.request.headers,
            mode: 'no-cors',
        });

        event.respondWith(fetch(newRequest));
Glycoprotein answered 29/9, 2024 at 10:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.