# Authentication using OAuth2 + OpenId Connect in Angular Single Page Application

Authentication and authorization are critical component of any application. In simple terms, authentication is a mechanism to verify if the user is the person who he/she is claiming to be. On the other hand, authorization is used to check for the accesses the user have. Authorization tells the application what actions the user is allowed to perform. In this article, we will focus on authentication only. Authorization will be covered in next articles of the series.

If you want your users to login to your application using Google, Facebook, GitHub or any other identity providers, then you need to use OAuth2 for authorization.

### OAuth2 and OpenId Connect
 [OAuth2](https://oauth.net/2/) is an industry-standard protocol for authorization. It is not meant for authentication. But, we need authentication as well. That's where  [OpenId Connect](https://openid.net/connect/)  comes into play. It is a simple identity layer on top of OAuth2 protocol.

### OAuth2 Components
3 components are involved while making single page application which uses OAuth2. 

1. **Authorization Server** takes care of authenticating and authorizing users using various methods - Username/Password, Google, Facebook, GitHub (you name it). We have some options for it. First is to build your own which will be very time and resources consuming, error-prone and not so secure task. Second is to use any existing authorization server and maintain that by yourself.  [Keycloak](https://www.keycloak.org/)  is a good example of it. Third option is to completely outsource this task to other identity providers.  [Okta](https://www.okta.com/) and [Auth0](https://auth0.com) are good examples of these providers. We will be using Okta for this series.

2. **Client Server** is responsible to display User Interface and data in the web browser. For now, we will use [Angular framework](https://angular.io/) to create it.

3. **API/Resource Server** exposes APIs to be consumed by Client Server and is responsible for storing all the data related to the application. It also restricts the user from accessing the resources which she doesn't have permission to. We will use [Spring Boot](https://spring.io/projects/spring-boot) to create API Server in next parts of the series.

### Setup Okta
Let's create one application and user in Okta identity platform for this application.
#### Create Application
1. Create a free developer account at `https://developer.okta.com/`.
2. Go to **Applications** > **Applications**.
3. Click on **Create App Integration**.
4. For **Sign-in method**, select *OIDC - OpenId Connect*.
5. For **Application type**, select *Single-Page Application*.

![Screenshot from 2021-12-02 22-42-25.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1638514028441/WuF7pzd19.png)

6. Click on **Next**.
7. For **App Integration name**, enter name best suitable to your application.
8. For **Grant Type**, choose *Authorization Code*.
9. For **Sign-in redirect URIs**, add *http://localhost:4200*.
10. For **Sign-out redirect URIs**, add *http://localhost:4200*.
11. For **Controlled Access**, select *Allow everyone in your organization*.
12. Click on **Save**.

After that, we can see application name, **Client ID**, **Okta domain** and other settings for the newly created application. `Client ID` and `Okta domain` will be used later in the article.
#### Create User
1. Go to **Directory** > **People**.
2. Click on **Add Person**.
3. Fill all the fields as given in the image below and click on **Save**.

![Screenshot from 2021-12-02 23-53-17.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1638514721847/J5lJyK9iz.png)

### Build Angular application
Now, let's dive into code and build an angular application which will use Okta as an identity provider to login the users. But hold on, let's make sure you have the right tools with you.
1. **Node.js** is a JavaScript runtime built on Chrome's V8 JavaScript Engine. It is needed to run the JavaScript code outside of the browser. If you don't have it in your machine, install it from [here](https://nodejs.org/en/).
2. **Angular CLI** is used to create angular apps. If you don't have it, follow the instructions [here](https://angular.io/guide/setup-local#install-the-angular-cli) to install it.

Now, my friend, you are ready to code.

Open terminal and run the following command to create a new angular app named `AngularOAuth2Demo`:
```
$: ng new AngularOAuth2Demo
```
This command might prompt you to select some options. Choose what is best for your application. After that, change your current directory to `AngularOAuth2Demo` app with the following command:
```
$: cd AngularOAuth2Demo
```
To manage all the requests for OAuth2 flow and to manage state of the logged in user in our angular app, we will use [angular-oauth2-oidc](https://www.npmjs.com/package/angular-oauth2-oidc) package. Install it into your app using the following command:
```
$: npm i angular-oauth2-oidc --save
```
Crete a file `src/app/config/authCodeFlowConfig.ts` to manage configurations related to OAuth2 flow. You will need to create `config` directory inside  `src/app` directory and then create the file. Replace the code of `authCodeFlowConfig.ts` with the following code:
```
import { AuthConfig } from "angular-oauth2-oidc";

export const authCodeFlowConfig: AuthConfig = {
  issuer: "<Your Issuer URI>",
  redirectUri: window.location.origin,
  clientId: "<Your Client Id>",
  responseType: "code",
  scope: "openid profile email",
  showDebugInformation: true
};
```
Let's break down this file and try to understand it. **Issuer URI** is a unique URI to identify the application for authentication and authorization purpose. You can find it on your application page in identity provider. If you created app in Okta, you will see **Okta Domain** for you app and the Issuer URI will be `https://<Your Okta Domain>/oauth2/default`.

The second part is `redirectUri`, which is used to redirect the user after authentication. This URI must be one of those `Sign-in redirect URIs` which you configured while making the app in Okta provider. We are using `window.location.origin` which will be `http://localhost:4200`, when the angular app will start, since Angular apps run on port 4200 by default. But, if you deploy your app to any server, say `https://yourcoolwebsite.dev`, then be sure to add this URI (`https://yourcoolwebsite.dev`) to Sign-in redirect URIs for your app in Okta or any other identity provider.

The `clientId` is unique to your application and you will find it on the application page in your identity provider. We are using `responseType` as `"code"`, so that identity provider will not send the `access token` and `id token` in query parameters (which is displayed in browser search bar). The next attribute `scope` is used to get access token with the given scopes from identity provider. The last attribute `showDebugInformation` is used to print some debugging information to the console.

Replace the code of `app.module.ts` with the following code:
```
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { OAuthModule } from 'angular-oauth2-oidc';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    OAuthModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```
Here, we imported `HttpClientModule` module from '@angular/common/http` package and `OAuthModule` from `angular-oauth2-oidc` package to handle auth flow and user state.

Now, replace the code of `app.component.ts` with the following code:
```
import { Component } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { authCodeFlowConfig } from './config/authCodeFlowConfig';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'AngularOAuth2Demo';

  constructor(private oauthService: OAuthService) {
    this.oauthService.configure(authCodeFlowConfig);
    this.oauthService.loadDiscoveryDocumentAndTryLogin();
  }

  login() {
    this.oauthService.initCodeFlow();
  }

  logout() {
    this.oauthService.logOut();
  }

  get name () {
    const claims = this.oauthService.getIdentityClaims();
    if (!claims) return null;
    const nameClaim = claims as {name: string};
    return nameClaim.name;
  }
}
```
Here, in the `constructor` we are configuring the `oauthService` to use `authCodeFlowConfig.ts` file for configuration. Then, we are trying to login the user if the session already exists.

In the `login` method, we are initiating the code flow for login. The `initCodeFlow` method of `oauthService` handles all the requests to and from the identity provider to get the access token. In the `logout` method, we are simply logging the user out.

The `name` setter method is used to extract `name` property from the claims, which we receive from the identity provider.

Now, replace the code of `app.component.html` with the following code:
```
<div>
  Welcome to Angular OAuth2 Demo

  <div *ngIf="name">
    Welcome, {{name}}<br />
    <button (click)="logout()">Logout</button>
  </div>
  <div *ngIf="!name">
    You are not logged in.
    <button (click)="login()">Login</button>
  </div>
</div>
```
Here, if the `name` is not empty, we are displaying a welcome message and a button which will call `logout` method when clicked. If the `name` is null or empty, another button will be displayed, which will call `login` method when clicked. And we have already created `login` and `logout` methods and `name` setter method in `app.component.ts`.

Now, its time to see the application in action. Run the following command in the terminal to start the application:
```
$: ng serve
```
In a private window of the browser, open `http://localhost:4200`. You will see a page with **Login** button. Click on login button. You will be redirected to Okta login page to enter username and password. Enter the username and password of the user which you created in Okta platform. After log in you will be redirected back to the angular application. Now, you will be able to see welcome message along with `Logout` button. Clicking on the logout button will logout the user and login button will appear again.

### Summary
 [Click here](https://github.com/himanshu-pareek/OAuth2SPA/tree/01-Authentication-Angular-OAuth2)  to view the source code on GitHub.
In this article, we used Okta as an identity provider to user OAuth2 in a Single Page Application. We still need to make resource server in order to complete the application. We will do that in next article. Also, we will discuss about some of the drawback of client side app and how to resolve them.

Your suggestions are welcome. Until then, Bye and keep learning...
