IFRCGo / cbs

Red Cross: Community-Based Surveillance
https://cbsrc.org/
Other
101 stars 110 forks source link

Determine how to handle the navigation/URL/routing etc. to stitch the distributed apps as one #403

Closed Virrum closed 6 years ago

Virrum commented 6 years ago

Description

The three(at the moment at least) webapps should feel as one. The navigation bar is a part of making it feel like one application. Further down, we need to decide how to pack it as one with the routings and composition of them. There are three or four possible ways of doing this. Two of them includes iframes. Yeah I know, but hear me out. It works.

Proposal 1

The distributed web apps, sends a GET to an endpoint, and get a chunk of html/css/js as a string, and prints it out.

Proposal 2

We create an Angular component that does more or less the same as mentioned in Proposal 1, but in a more controlled way.

Proposal 3

The navigation app works as a display/router/proxy, with the navigation on top, and the rest of the viewport is an iframe. We know the content of the navigation and the width of the viewport. We can then style the rest and still have it responsive. We have full control over the output of the navigation, routerlinks and very little hurdles.

Proposal 4

The opposite of Propsal 3, that we have a nginx router or something in front, that reads the URL and send to the corresponding application. The application is responsible to write the navigation bar in an iframe. Again, we know the content, and we can style the iframe responsive.

Virrum commented 6 years ago

applicationasentrypoint navigationasentrypoint

roarfred commented 6 years ago

Will all four alternatives:

My immediate thoughts are in favor of the shared component. Even if there is a dev-dependency, and some duplication, there might be value in all applications working independently, not sharing a single point of failure. (Assuming a negative answer to the second question and the navigation service might being a "single point of failure")

Virrum commented 6 years ago

That is great inputs @roarfred .

Summary

Angular package

More work to care about. Not only are you building a navigation bar, but a versioned package as well. And when updating the navigation, you need to update the package in all the other web applications as well. So what happens is that their not independent any more. You'll end up with three different headers if the deployments are out of sync.

iFrame on each application

You will have a single line of html, with the href to the navigationbar, some styleing of that iframe, I'm willing to think of inline styling even. Then all solutions are independent of each other when it comes to build, deploy and uptime. If the navigation service should break, you'll still get the applications, but with a blank navigation bar. And when you do a new deploy of the navigation, all the other three will automatically have the latest version without a touch.

I'm so surprised I ended up here, but my vote goes for the iframe solution 😂 haha

alexanderhoset commented 6 years ago

Your idea is then to make the navbar deployable and include it as a iframe in the different contexts @Virrum ? If , so I can agree to that

beatfactor commented 6 years ago

If I may offer my input here, in my experience, a layout based on iframes poses several issues, so I am wondering if we can revisit this decision. From what I can tell, some of these issues have to do with:

  1. usability (e.g. page scrolling, navigating using back/forward browser buttons);
  2. performance (iframes might have a negative impact on page loading speed, caching can be problematic);
  3. accessibility (potentially more difficult to navigate using a keyboard, issues for screen readers etc.);
  4. search engine optimisation (content in an iframe is not considered part of the parent page, so it may not be indexed);
  5. automated testing (UI tests usually don't work very well with iframes);
  6. security - using iframes makes it more difficult to protect against attacks such as click-jacking, and maybe also cross-site scripting;
  7. authentication - with OAuth 2, iframes could introduce problems with sharing the session data between the parent frame and the individual iframes.

Having that said, an iframes based layout wouldn't be my first choice and, if we can, I think we should avoid this approach altogether. How about this instead:

  1. either have the navigation included as a separate component in each app, then have an nginx proxy to manage the routing;
  2. or, have the individual web apps built as separate components and packaged during a common build step, then deployed together as one app (could be also a separate repository).

Option one would probably be faster, but it would involve page reloads when navigating between sections, and so it would be suboptimal. Second option might be a little more difficult to get it working initially, but it would provide substantially more value, in terms of user experience. And regarding the individual apps being independent, I'm not sure if there's a lot to gain there. If all the frontend code sits together on the same server, it's easier to deploy and also caching will work better.

karolikl commented 6 years ago

@Virrum, do you have any input on @beatfactor's comment above?

Virrum commented 6 years ago

Sorry, have been offline for a couple of days.

I'll share my thoughts one by one :)

  1. Not a problem here. We have a set height, it wont have unwanted scrolls. It'll be styled responsively in both parts to avoid scrolling. history buttons will work. It's the apps URLs that will count, and the links in the navigation will have _parent as target.
  2. yes, it might be some extra load, but the navigation bar is really slim, and don't need a lot of styles or javascript. So when we got a solution that works, we'll trim away the code that isn't necessary. (99% of bootstrap I guess)
  3. Yes, this is something we definitely need to make sure works. I found this jsfiddle testing exactly this: http://jsfiddle.net/gjng7dgg/4/ - but yes, we need to keep our tongue straight here.
  4. Not a problem for this matter. These apps is behind login either way.
  5. I have no experience with this. But the navigation bar is an application itself, so all separate apps can be responsible for it's own UI automated test.
  6. We are in full control of what url and domain to include both in code and the ifram, so I can't see that this will be a problem in this matter.
  7. All four apps, navigation included as an app, will most likely as far as I have understood, have the same top level domain and subdomain. Will it then still be a problem?

Very few has iframes as the first go to solution, and that includes myself. But after digging into it the last few months, I have come to see that it might be a great solution for this usage.

  1. Yes, it could be an angular component in each app. The thing then, when changing something in the navigation, it requires three deployments to get it out. And that kind of breaks the intention of using bounded context. And what if one of the apps is not deployable at the moment, or two? In worst case, you can end up with three apps with three different navigations that was supposed to work as one.
    • With iframes you actually have three, four when you include the navigation app, that actually works totally separate from each other. They are completely independent. When deploying a new version of the navbar, all the three apps will get the latest version without even knowing it.
  2. We (Dolittle) have been talking a lot about doing something like this. It's not set how and in what level, but we are talking about some solution to have an extra build step that compose one app based on many. But there are so many things to uncover before we can do this, so it's not a ready to leave the drawing board yet.

So the fastest and most independent way is in my opinion iframes, at the moment. And if you told me in august that I was to suggest that as a preferred solution in the beginning of 2018, I wouldn't believe you.

beatfactor commented 6 years ago

I still have some concerns about usability and performance, but my biggest one is regarding authentication. As far as I know, there is a decision to use Azure B2C. I have some experience with B2C, having worked last year with it on a similar kind of setup, with four independent web apps, each running on its own subdomain and using single sign-on.

The main issue with this is when switching between the apps. I'm not entirely sure what the deployment setup plan is, but at the moment each app is running individually on its own subdomain, which means that we will need to validate the authentication data (access token) with B2C for each individual app, by performing a single sign-on authentication attempt. If that will the case, then we will probably hit a dead end, because it's not possible to open the B2C pages within an iFrame, according to the docs.

beatfactor commented 6 years ago

Actually I realised that the individual apps are sharing the same domain name, so if the authentication can be performed by the main frame, maybe it's possible to share it with the iframes. However, the MSDN docs do mention that "the security community in general and the OAUTH2 specification, recommend against using iFrames for identity experiences" and I think it is quite evident that the use of iframes in a B2C enabled application creates some complications.

Virrum commented 6 years ago

Great input, I have no answer to it. The great thing about the iframe solution is that it is very easy to set up and test. I have an implementation in admin, almost ready for a PR, I haven't had time to complete it yet. Hope to get it done next week. And if it turns out to don't work, we delete the component and solve it another way. Deleting code is pure fun, so I don't see any problems not to try it out before we speculate back and forth 😉

eprom commented 6 years ago

@beatfactor, @Virrum Great & insightful discussion! Having the same domain name for all apps minimize the security risks that comes with iFrame. The apps can seamlessly share the session and data with same origin policy. We planned to discuss authentication/authorization part on next code evening (next week) @beatfactor it will be great to have you remotely or in person during the discussion.

beatfactor commented 6 years ago

Yes, I plan to be there, probably somewhere in the afternoon, after 5 o'clock.