Creating a Backstage.io App with Google SSO Authentication
Published: 2022-09-12 01:39:52

#**Before you continue**

Before you continue with this article, you **MUST** make sure that all the Backstage.io prerequisites are installed in you local environment.

All the details can be found here: [https://backstage.io/docs/getting-started/#prerequisites](https://backstage.io/docs/getting-started/#prerequisites)

### **Also! you can find the source of this app in my github account: [https://github.com/pqzada/backstage-demo-app](https://github.com/pqzada/backstage-demo-app)**

#**Creating a new Backstage.io App**

To create a new Backstage.io App you must run the following command:

```bash
npx @backstage/create-app
```

This it’s going to ask you for the app name. In this exercise, we are going to use **backstage-demo-app**.

```bash
? Enter a name for the app [required] backstage-demo-app
```

This may take a while… just be patient.

If it asks you for a database, select **PostgreSQL**. If don’t, that’s ok. We will configure it in the next section.

When the installation is done, you should enter the app folder and run the dev environment.

```bash
cd backstage-demo-app && yarn dev
```

#**Database configuration**

Now that our Backstage.io App is created and running, we are going to create a PostgreSQL container with docker and complete the configuration in our App.

> Note: If you already have PostgreSQL installed in your local environment, you can skip the next section and go to the PostgreSQL configuration.
> 

## **Creating a PostgreSQL container with Docker**

To avoid having to install the database in our local environment, we are going to create a docker container with the last image available for Postgres.

Go to the root of your application and create a `docker-compose.yaml` file. Then paste the following code.

```yaml
version: '3.8'
services:
  db:
    image: postgres:latest
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - '5432:5432'
    volumes:
      - db:/var/lib/postgresql/data
volumes:
  db:
    driver: local
```

Run the container with the following command:

```bash
docker-compose up -d
```

If everything it’s ok, then the response should be like this:

```bash
Starting backstage-demo-app_db_1 ...done
```

## **Configuration of PostgreSQL in our Backstage Demo App**

Stop out Backstage Demo App (`CTRL + C`) and go to the root directory using the terminal. Execute the following command to start the PostgreSQL client configuration:

```bash
yarn add --cwd packages/backend pg
```

Edit the `app-config.yaml` file and set your PostgreSQL configuration using the data from the previous steps (look in the `docker-compose.yaml`).

Search for the **backend > database** section and replace the content with the following:

```yaml
database:
  client: pg
  connection:
    host: 127.0.0.1
    port: 5432
    user: postgres
    password: postgres
```

Start Backstage again.

#**Google SSO configuration**

To enable Google SSO in our Backstage Demo App we must:

- Create OAuth credentials for our app
- Set the OAuth credentials in our app-config.yaml file
- Add the Google Auth Provider to the Sign In page
- Configure Google Provider to support Sign In

## **Create OAuth credentials for our app**

To log in using the Google SSO we need to create OAuth credentials first. If you don’t know how to do this, check this other article:

[How to configure the Google Authentication Provider for Backstage.io](https://dev.to/pqzada/how-to-configure-the-google-authentication-provider-for-backstageio-4elg)

## **Set the OAuth credentials in our app-config.yaml file**

Open your `app-config.yaml` and set the `auth` config. It should end up looking like this:

```yaml
auth:
  environment: development
  providers:
    google:
      development:
        clientId: YOUR_CLIENT_ID
        clientSecret: YOUR_CLIENT_SECRET
```

## **Add the Google Auth Provider to the Sign In page**

Next, we must add the provider to the Sign In page. To do this, open the `packages/app/src/App.tsx` file, and below the last `import` line, add the following:

```tsx
import { googleAuthApiRef } from '@backstage/core-plugin-api';
import { SignInProviderConfig, SignInPage } from '@backstage/core-components';

const googleProvider: SignInProviderConfig = {
  id: 'google-auth-provider',
  title: 'Google',
  message: 'Sign in using Google',
  apiRef: googleAuthApiRef,
};
```

Then search for `const app = createApp({` and below `apis,` add:

```tsx
const app = createApp({
  apis,
  components: {
    SignInPage: props => (
      <SignInPage {...props} auto providers={['guest', googleProvider]} />
    ),
  },
  bindRoutes({ bind }) {
```

At this point, we have added the`SignInPage` component for our Google Provider.

## **Configure Google Provider to support Sign In**

Open the file `packages/backend/src/plugins/auth.ts` and change the `createPlugin`so it looks like this:

```tsx
export default async function createPlugin(
  env: PluginEnvironment,
): Promise<Router> {
  return await createRouter({
    logger: env.logger,
    config: env.config,
    database: env.database,
    discovery: env.discovery,
    tokenManager: env.tokenManager,
    providerFactories: {
      ...defaultAuthProviderFactories,
      google: providers.google.create({
        signIn: {
          resolver: async (info, ctx) => {
            const {
              profile: { email },
            } = info;

            if (!email) {
              throw new Error('User profile contained no email');
            }

            const [name] = email.split('@');

            return ctx.signInWithCatalogUser({
              entityRef: { name },
            });
          },
        },
      })
    },
  });
}
```

The important here is that we added some specific **logic to resolve the sign in with the Google Provider**. So, take some time to understand it.

More information about the identity resolver can be found here: [https://backstage.io/docs/auth/identity-resolver](https://backstage.io/docs/auth/identity-resolver)

## **Adding our user to the catalog**

If we check the previous code, the login it’s going to be done with the catalog (`signInWithCatalogUser`), searching for an `entityRef`with the `name`. This `name` is our email without the `@gmail.com`.

If we try to login right now we are going to get an “**User not found**” error like this:


![https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nrhfnkie4j8fg19ipl4.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nrhfnkie4j8fg19ipl4.png)

This is because our user doesn’t exists in the catalog. So, let’s try to add it.

In the root of our app create new folder called `catalog` and in the inside a new file called `org.yaml`. Add this content to the file:

```yaml
---
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
  name: users
spec:
  type: team
  children: []
---
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
  name: pqzada
spec:
  memberOf: [users]
```

Then, open the `app-config.yaml` file and add this lines in the locations sections.

```yaml
locations:
		...
    - type: file
      target: ../../catalog/org.yaml
      rules:
        - allow: [User, Group]
```

With this, we are telling our app that search in the `org.yaml` for users and groups.

And now if we restart our app and try to log in with our Gmail account… works OK!


![https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqizqtxfe7r9kdrf83gk.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqizqtxfe7r9kdrf83gk.png)

Any doubts? comment below!! or reach me on Twitter: [https://twitter.com/pqzada](https://twitter.com/pqzada)