Blog

You are here: Blog / Implement Okta Authentication in Angular


  • Implement Okta Authentication in Angular

    In this blog, we will walk you step by step process of how to integrate authentication in angular app by Okta. Before we start, consider that you have already sign up with Okta account if not please click here


    Following are steps for implementation:


    Step1: Add an OpenID Connect Client in Okta

    • Log into the Okta Developer Dashboard
    • Click on Application menu and Create new application by click on “Add Application”
    • Choose Single Page App (SPA) as the platform and then populate your new OpenID Connection application with following settings and theirs values.

    SettingValue
    Application NameOpenID Connect App (must be unique)
    Login redirect URIshttp://localhost:4200/callback
    Logout redirect URIshttp://localhost:4200/login
    Allowed grant typesAuthorization Code


    Step 2: Create an Angular App

    To create the new angular application if you have not installed the Angular CLI then first install the angular CLI with following command

    PS E:\>npm install -g @angular/cli

    Run the CLI command ng new and provide the name my-app, as show below. As we are implementing Okta Authentication, given name is “Okta-app”

    PS E:\> ng new Okta-app 


    Step 3: Install Dependencies

    Install the dependencies NPM packages as below

    PS E:\> cd okta-app 

    PS E:\> npm install @okta/okta-signin-widget --save

    PS E:\> npm install @okta/okta-angular --save


    Step 4: Create Routes

    You'll need to provide these routes in your sample application, so that we can sign the user in and handle the callback from Okta.

    • /: A default page to handle basic control of the app.
    • /protected: A protected route that can only be accessed by an authenticated user.
    • /login: A custom login page to handle signing users into your app.
    • /implicit/callback: Handle the response from Okta and store the returned tokens.


    Step 5: Implement Login and Logout Functionality

    Open the app.component.html and put the login page code as per below code snippet.

    
    <button routerLink="/"> Home </button>
    <button *ngIf="!isAuthenticated" routerLink="/login" > Login </button>
    <button *ngIf="isAuthenticated" (click)="logout()" > Logout </button>
    <button routerLink="/protected" > Protected </button>
    <router-outlet></router-outlet>

    To handle the logout call open the app.component.ts file and put following snippet.

    
    export class AppComponent {
      isAuthenticated: boolean;
      constructor(public oktaAuth: OktaAuthService, public router: Router) {
        this.oktaAuth.$authenticationState.subscribe(
          (isAuthenticated: boolean)  =>: this.isAuthenticated = isAuthenticated
        );
      }
    
      async ngOnInit() {
          this.isAuthenticated = await this.oktaAuth.isAuthenticated();
      }
    
      login() {
        this.oktaAuth.loginRedirect('/profile');
      }
    
      async logout() {
        await this.oktaAuth.logout();
        this.router.navigateByUrl('/');
      }
    }


    Step 6: Create the new component called protected

    Create a new component called protected which will use to identify that authentication is working or not, put following code snippet.

    
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-secure',
      template: `{{message}}`
    })
    export class ProtectedComponent {
      message;
    
      constructor() {
        this.message = 'Protected endpoint!';
      }
    }


    Step 7: Create the new component called login

    Create new component called login and put following code snippet on it:

    
    export class LoginComponent {
      signIn;
      widget = new OktaSignIn({
        baseUrl: 'https://${https://dev-322431.okta.com}',
        authParams: {
          pkce: true
        }
      });
    
      constructor(oktaAuth: OktaAuthService, router: Router) {
        this.signIn = oktaAuth;
        router.events.forEach(event =>: {
          if (event instanceof NavigationStart) {
            switch(event.url) {
              case '/login':
                break;
              case '/protected':
                break;
              default:
                this.widget.remove();
                break;
            }
          }
        });
      }
    
      ngOnInit() {
        this.widget.renderEl({
          el: '#okta-signin-container'},
          (res) =>: {
            if (res.status === 'SUCCESS') {
              this.signIn.loginRedirect('/', { sessionToken: res.session.token });
              // Hide the widget
              this.widget.hide();
            }
          },
          (err) =>: {
            throw err;
          }
        );
      }


    Step 8: Update the app.module file

    Open the app.module.ts file and update the update modules which include your project components and routes. Following is code snippet for the app.module.ts

    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    import {
      OktaAuthModule,
      OktaCallbackComponent,
      OktaAuthGuard
    } from '@okta/okta-angular';
    
    import { AppComponent } from './app.component';
    import { ProtectedComponent } from './protected.component';
    import { LoginComponent } from './login.component';
    
    const config = {
      issuer: 'https://dev-322431.okta.com/oauth2/default',
      redirectUri: 'http://localhost:4200/callback',
      clientId: '0oai1wrfhfAr9ZYX74x6',
      pkce: true
    }
    
    export function onAuthRequired({ oktaAuth, router }) {
      // Redirect the user to your custom login page
      router.navigate(['/login']);
    }
    
    const appRoutes: Routes = [
      {
        path: 'implicit/callback',
        component: OktaCallbackComponent
      },
      {
        path: 'login',
        component: LoginComponent
      },
      {
        path: 'protected',
        component: ProtectedComponent,
        canActivate: [ OktaAuthGuard ],
        data: {
          onAuthRequired
        }
      }
    ]
    @NgModule({
      declarations: [
        AppComponent,
        LoginComponent,
        ProtectedComponent
      ],
      imports: [
        BrowserModule,
        RouterModule.forRoot(appRoutes),
        OktaAuthModule.initAuth(config)
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }


    Step 9: Read the access token after logged in

    Your Angular application now has an access token in local storage that was issued by your Okta Authorization server. You can use this token to authenticate further server API requests.

    Just to test the message of Authentication you can create new component called message.component.ts and put following code snippet.

    
    import { Component, OnInit } from '@angular/core';
    import { Http, Headers, RequestOptions } from '@angular/http';
    import { OktaAuthService } from '@okta/okta-angular';
    import 'rxjs/Rx';
    
    interface Message {
       date: String,
       text: String
    }
    
    @Component({
      template: `
        <div *ngIf="messages.length">
          <li *ngFor="let message of messages">{{message.message}}</li>
        </div>
      `
    })
    export class MessageListComponent implements OnInit{
      messages: Array<Message> [];
    
      constructor(private oktaAuth: OktaAuthService, private http: Http) {
        this.messages = [];
      }
    
      async ngOnInit() {
        const accessToken = await this.oktaAuth.getAccessToken();
        const headers = new Headers({
          Authorization: 'Bearer ' + accessToken
        });
        // Make request
        this.http.get(
          'http://localhost:{serverPort}/api/messages',
          new RequestOptions({ headers: headers })
        )
        .map(res => res.json())
        .subscribe((messages: Array<Message>) => messages.forEach(message => this.messages.push(message)));
      }
    }
    

    Done!

    Run the Application.