From 14c9f68f38f20be66458334a19019bc703c3f719 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 21 Mar 2024 18:23:39 +0100 Subject: [PATCH] docs: start drafting a public entrypoint tutorial Signed-off-by: Camila Belo --- docs/tutorials/enable-public-entry.md | 118 ++++++++++++++++++++++ microsite/sidebars.json | 1 + plugins/app-backend/src/service/router.ts | 12 --- 3 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 docs/tutorials/enable-public-entry.md diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md new file mode 100644 index 0000000000..a25d1a8704 --- /dev/null +++ b/docs/tutorials/enable-public-entry.md @@ -0,0 +1,118 @@ +--- +id: enable-public-entry +title: Enabling public entry point +description: A guide for how to experiment with public and protected Backstage app bundles +--- + +# Enable Public Entry (Experimental) + +In this tutorial, you will learn how to restrict access to your main Backstage app bundle to authenticated users only. + +It is expected that the protected bundle feature will be refined in future development iterations, but for now, here is a simplified explanation of how it works: + +Your Backstage app bundle is split into two code entries: + +- Public entry point containing login pages; +- There is also a protected main entry point that contains the code for what you see after signing in. + +With that, Backstage's cli and backend will detect public entry point and serve it to unauthenticated users, while serving the main, protected entry point only to authenticated users. + +## Requirements + +- The tutorial will only work for those using backstage-cli to build and serve their Backstage app. + +## Trying out this feature + +1. Add a `index-public-experimental.tsx` to your app `src` folder; + +2. Prepare an unauthenticated version of your application. This will be the public entry point for your site: + + ```tsx title="in packages/app/src/index-public-experimental.tsx" + import React from 'react'; + import ReactDOM from 'react-dom/client'; + import { createApp } from '@backstage/app-defaults'; + import { AppRouter } from '@backstage/core-app-api'; + import { + AlertDisplay, + OAuthRequestDialog, + SignInPage, + } from '@backstage/core-components'; + import { + configApiRef, + createApiFactory, + discoveryApiRef, + } from '@backstage/core-plugin-api'; + import { RedirectToRoot } from '@backstage/plugin-auth-react'; + import { providers } from '../src/identityProviders'; + import { AuthProxyDiscoveryApi } from '../src/AuthProxyDiscoveryApi'; + + // Notice that this is only setting up what is needed by the sign-in pages + const app = createApp({ + apis: [ + createApiFactory({ + api: discoveryApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => + AuthProxyDiscoveryApi.fromConfig(configApi), + }), + ], + components: { + SignInPage: props => { + return ( + + ); + }, + }, + }); + + const App = app.createRoot( + <> + + + + {/* This is a special component that does the magic to redirect users to access the home page of your authenticated application version */} + + + , + ); + + ReactDOM.createRoot(document.getElementById('root')!).render(); + ``` + +3) Then ensure your main entry is also protected by the experimental app provider, as shown in the following example: + +```tsx title="in packages/app/src/index-public-experimental.tsx" +// ... +export default app.createRoot( + <> + + + + {/* For now, this is just a temporary solution to ensure the user remains logged in properly and has access to the main app content. */} + + + {routes} + + + , +); +``` + +4. You're now ready to build your front-end app: + +```sh +yarn workspace example-app build +``` + +5. And also serve it from your Backstage app backend: + +```sh +yarn start-backend:next +``` + +6. Finally, access http://localhost:7007 to see the public app being served (note that only a minimal app is being served). Log in and you will be redirected to the main app home page (check the protected bundle being served from the app-backend after the redirect). diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 7d941e5821..62e5774098 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -504,6 +504,7 @@ "tutorials/yarn-migration", "tutorials/migrate-to-mui5", "tutorials/auth-service-migration", + "tutorials/enable-public-entry", "tutorials/setup-opentelemetry" ], "Architecture Decision Records (ADRs)": [ diff --git a/plugins/app-backend/src/service/router.ts b/plugins/app-backend/src/service/router.ts index e46a80c27d..70466da001 100644 --- a/plugins/app-backend/src/service/router.ts +++ b/plugins/app-backend/src/service/router.ts @@ -170,18 +170,6 @@ export async function createRouter( const enablePublicEntryPoint = await fs.pathExists(publicDistDir); - /* - TODO: - - Cookie refresh - - Backend endpoint, /.backstage/v1-cookie - - Frontend provider - - Remove issueUserCookie from HttpAuthService and move to auth-node - - Move RedirectToRoot to auth-react - - Document index-public-experimental & how to use - - Logout? How do we clear the cookie? - - */ - if (enablePublicEntryPoint && auth && httpAuth) { const publicRouter = Router();