OAuth is the undisputed standard for authenticating over the web or in native mobile apps. The promise of one-click signups and logins has obvious appeal, but getting this up and running is often quite challenging. Over the years we have heard countless horror stories from developers who have spent weeks trying to add OAuth support to their applications, with varying degrees of success.

This article provides a 15 minute, step-by-step guide to adding OAuth support to a CLI-generated Angular application using Firebase. We will implement OAuth with a Google account, but other platforms supported by Firebase include: Facebook, Twitter, and GitHub.

Firebase

But first, what is Firebase? Firebase got its start as a realtime cloud-hosted NoSQL database supporting multi-user synchronization. Since being acquired by Google in October of 2015 it has become an entire publishing platform for web and mobile applications. Many major companies, including Lyft, Shazam, The New York Times, and NPR, use Firebase to support their apps . Some of these applications see over 100 million monthly users and update the database more than 3,000 times per second, providing strong evidence that the platform can scale.

At Andromeda, we use Firebase to build and deploy solutions rapidly without the high cost of platform and infrastructure maintenance. For example, our parking app FlexePark lets business owners turn their private parking lots into public paid lots after business hours. FlexePark uses Firebase to authenticate users with their existing social media accounts for faster and easier signups, but also supports traditional email/password accounts.

You can also have one-click signups in your applications by following the step-by-step instructions below.

Getting Started

The following example walks you through the creation of a fully-functional Angular application with Google authentication. This demo will include the following features:

Login with a Google account using OAuth

Logout

Retrieving user metadata from the auth provider

Protecting a URL from unauthenticated access

We will be using the AngularFire2 library to work with Firebase from our code. Although Firebase provides a universal JavaScript API, AngularFire provides a convenient Angular wrapper around this functionality, allowing us to more easily add Firebase features within our framework.

Once in, you’ll need to click Add project and type a new project name.

Because we are going to implement OAuth, we need to activate authentication within the Console. Click on Authentication and then Sign-In Method, and finally select Google from the list of Sign-in providers.

Part of implementing OAuth is the generation of API keys with the authentication provider (such as Facebook or Twitter). This involves creating a developer account with that provider, and copying the keys into Firebase. Since Firebase is a Google product, you already have a developer account by virtue of signing up for Firebase. Therefore, Firebase requires no manual creation of API keys for OAuth. Simply click the Enable slider and then Save.

Configure Firebase

Now we need to initialize Firebase within our application in order to connect to the authentication services. Go to the overview section in the firebase console and click on Add Firebase to your web app.

This will give you configuration details you can copy into your project. Copy just the JSON values in the middle. (We don’t want the HTML script tags, because we will be inserting code directly into a TypeScript file.)

Now create a new firebase key in the environments.ts file in your Angular project and paste in the copied values.

(Note: You will need to perform the same update to your environment.prod.ts file if you want to support Firebase auth from a --prod build.)

The final setup step is to initialize the Firebase API using these configuration values. This is done in the app.module.ts file using the AngularFireModule, which provides an Angular-friendly way to initialize the firebase API. Be sure to update your file to include the following code.

Login Component

Before we can authenticate, we need an Angular component to provide the user with a way to access this functionality. Our login component will simply provide Login and Logout buttons, and will bind to the root URL.

Create component

Use the Angular CLI to generate a new component named login.

$ ng generate component components/login

Start by stubbing out two functions, login and logout. We will add the functionality a bit later.

Routing

Next we will configure a route to the Login component so that we can view and interact with it. Create a new file named app-routing.module.ts within the app folder and set the contents as follows, noting that we are importing the LoginComponent and setting it to the root path.

And finally we should set up the home page with something relevant to our demo. This should include navigation, along with a router-outlet to display our component. Replace the existing app.component.html file with something like this:

Validation

At this point you should be able to run the application for a quick check.

$ npm start

You can preview the application at http://localhost:4200/ and should see the simple screen shown below. Note that clicking Login and Logout will write a message to your developer console. You can view the console in Google Chrome by pressing F12.

Authentication Service

Now that we have the Login component set up, it’s time to tie it into the Firebase authentication provider. We’ll do this by creating an Angular authentication service. Although this is not strictly necessary (you could just use the AngularFire authentication services directly from the login component), it provides a couple immediate benefits. You can:

Decorate authentication (including the creation of a User Profile in the database) without refactoring code

Write unit tests against your component code without having to mock the 3rd party AngularFire2 library

Create service

Use the Angular CLI to generate a new authentication service.

$ ng generate service services/authentication

Import AngularFireAuth into your service to access the authentication functions. Because Angular Fire uses observables, we also need to import Observable. You will also need to import the firebase module in order to reference the User type and the Auth Providers.

Define the authInfo observable, which will return a Firebase User upon login. Add AngularFireAuth to the constructor and use this to initialize authInfo by setting it to authState, which is an Observable managed by AngularFire. This authInfo property will be your way to obtain information about the currently authenticated user.

Add login and logout functions to the service and implement them by calling the appropriate methods from AngularFire. The signInWithPopup method will launch a popup window to connect to Google for authentication. The result of this method is a Promise that we are using here to log to the developer console.

Another option would be the signInWithRedirect method, which would redirect to Google and then back to your application. The downside of this approach on a single-page application is that your entire application will unload and then re-initialize, which can have performance implications, among other considerations.

Both of the sign-in methods require a Provider, which is available from the core Firebase API. Supported providers include Google, Facebook, Twitter, GitHub, phone, email/password, and anonymous.

Now let’s display the Name of the logged-in user, and hide the Login/Logout buttons when a user is already logged in. Note that authInfo is an Observable, so we must use async to avoid errors when the value has not been set.

Validation

At this point you should have a simple page with header text, navigation links, user name (assuming you have logged in), and either a Login or Logout button, based upon your authentication status.

Route Protection

Now you’ve successfully implemented OAuth with Firebase, but there’s one more thing to cover to make this a comprehensive example of authentication in Angular. It is quite common to want to restrict access to one or more pages until the user has logged in. So let’s add this capability to our example now.

Create component

To start, we’ll need to create a new component to protect. Let’s just call it ‘protected’.

$ ng generate component components/protected

And then we need to set up a route to this component. We’ll use /protected.

At this point you can freely access /protected even without being logged in. To change this, we will be making use of CanActivate, which expects a Boolean to determine whether the route should be resolved. We will create a new service that will return a boolean Observable based upon authentication status to satisfy the requirements of CanActivate.

Create service

Use the Angular CLI to generate a new authGuard service.

$ ng generate service services/authGuard

Now we must implement the service using the previously created AuthenticationService in order to react to changes in the authenticated state. The take(1) captures the first object resolved by the Observable (which will be a firebase.User). The map(...) converts the authInfo into a boolean value that should be true whenever it isn’t falsey (null or undefined).

In our example, the do(...) performs a redirect to the login URL whenever the user is not authenticated. This is just one possible way to handle unauthenticated access to a protected resources, but it both facilitates logins and addresses the case where a user is logged out while on a protected URL.

Validation

At this point you should have navigation links for both Login and Protected. Clicking Protected while not logged in should navigate to the login URL (/). Note that clicking this link while already on this default root URL will make it appear to do nothing. Upon logging in, clicking Protected should display the message “protected works!”

Congratulations

In about 15 minutes you have learned how to use Firebase to add OAuth to your Angular applications! This starter application allows users to log in using a Google Account and to logout, while restricting access to URLs for unauthenticated users. You can now use this as a base application for future projects to get started with OAuth already baked-in.

All of the example code used in this article is available on GitHub if you would like to clone our project to get started right away. You will need to copy your own Firebase configuration values to get it running.

For more hands-on experience developing with Firebase, check out our workshop, Playing With Fire.

Michael is a Co Founder and Product Architect for startups Andromeda, FlexePark, and M2D2. For more than 20 years he has been writing code and geeking out over cool technology. He is passionate about keeping things simple and focusing on what provides real value to the end user. Michael enjoys helping other developers grow in their career, speaking at conferences, user groups, and coding academies. In 2015 he wrote Programming Languages ABC++ to share programming languages with children.

Focusing on web interfaces that are beautiful, functional, and usable, Martine delivers products that adhere to WCAG 2.0 and Section 508 for accessibility and compliance. She approaches User Experience from both Art and Science, drawing from her degrees in Psychology and Visual Communications. Martine has worked as an artist, educator, and consultant since 2005, and is the UX Development Lead for both Andromeda and FlexePark.

Michael has worked with a wide variety of stacks in both the private and public sector, including Hybrid Mobile Apps and Enterprise Java Applications. Pushing the limits of web technology he constantly looks for the latest and greatest tools, building fast, and flexible solutions. His work can be found on Google play and the Apple Store, as well as being used by thousands of people supporting government programs.
Michael thrives in a fast paced leading edge environment where he can make the largest impact on the technology stack, feature se...