JSON Web Tokens – JWT – Angular

Im ersten Teil haben wir einen Blick auf JWT im Zusammenspiel mit Java EE geworfen. Heute soll es um die Client-Seite gehen und die Verwendung von JWT im Kontext von Angular (v. 4)

app.png

Für Angular gibt es inzwischen einige Zusatzbibliotheken die den Umgang mit JWT wesentlich vereinfachen. Eine davon werden wir unserem Projekt wie gewohnt über NPM hinzufügen:

npm install @auth0/angular-jwt

Diese neue Version ist ab Angular 4 verfügbar und verwendet zur Implementierung die eingeführten HTTP-Interceptoren. Die anschließende Verwendung ist denkbar einfach. Wir konfigurieren JWT über unser app.module und definieren eine Methode welche den JWT Token zur Verfügung stellt. In diesem Beispiel legen wir diesen nach einem Login in den LocalStorage ab und rufen diesen bei der Initialisierung der Anwendung ab:

 

import { JwtModule } from '@auth0/angular-jwt';

export const getToken = function() {
  return localStorage.getItem('JWT-TOKEN');
}

@NgModule({
    ...
    JwtModule.forRoot({
      config: {
        tokenGetter: getToken,
        whitelistedDomains: ['localhost:8080']
      }
    })
  ]
export class AppModule { }

Hier zu sehen ist auch die benötigte Deklaration der Domains an die unser Token geschickt werden soll (da viele Anwendungen mit mehreren Servern kommunizieren und nicht alle Requests mit den zusätzlichen Headern versehen werden sollen).

In Folge dieser Deklaration erhalten alle unsere Requests an die definierten Hosts einen entsprechenden Authentifikation-Header, ganz automatisch:

request_header_jwt

Token? Her damit !

Natürlich muss dieser Token erst mal den Weg in unsere Anwendung finden. Der Token wird vom Server bereitgestellt und lässt sich mit einer sehr einfachen Login Methode implementieren:

  login(username: string, password: string): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.http
        .post('http://localhost:8080/angular-jwt-1.0-SNAPSHOT/rest/login'
           , { username, password }, { responseType: 'text' })
        .subscribe((resp: string) => {
          localStorage.setItem('JWT-TOKEN', resp);
          resolve(true);
        }, error => reject);
    });
  }

Du? Nicht. Guards

Mit dem Vorhandensein dieses Tokens lässt sich nun auch sehr leicht der Zugriff auf bestimmte Teile der Seite verhindern. Dazu verwenden wir so genannte Guards, die beim Routing greifen und prüfen ob eine bestimmte Route überhaupt verwendet werden darf:

Guard

export const APP_ROUTES: Routes = [
  ...
  { path: 'protected', component: ProtectedComponent, canActivate: [AuthGuardService] },
  { path: 'notallowed', component: NotAllowedComponent }
]

Route-Definition

@Injectable()
export class AuthGuardService implements CanActivate {

  constructor(private router: Router) { }

  canActivate(): boolean {
    const allowed = localStorage.getItem('JWT-TOKEN') !== null;

    if (!allowed) {
      this.router.navigateByUrl('notallowed');
    }
    return allowed;
  }
}

JWT ist einer der weit verbreiteten Techniken für die Zustandslose Authentifizierung und den Austausch verschlüsselter Daten. Angular bietet zusammen mit der hier gezeigten Bibliothek eine sehr einfache Möglichkeit diese Technik zu nutzen.

Live? Farbe? github/GEDOPLAN

Advertisements

Über Dominik Mathmann
Dominik Mathmann arbeitet als Berater, Entwickler und Trainer bei der GEDOPLAN GmbH. Auf Basis seiner langjährigen Erfahrung in der Implementierung von Java-EE-Anwendungen leitet er Seminare, hält Vorträge und unterstützt Kunden bei der Konzeption und Realisierung von Webanwendungen vom Backend bis zum Frontend. Sein derzeitiger Schwerpunkt liegt dabei auf der Entwicklung von JSF-Anwendungen. Er sieht die stärker werdende Position von JavaScript-Frameworks jedoch positiv und beschäftigt sich darüber hinaus mit Webframeworks wie AngularJS.

4 Responses to JSON Web Tokens – JWT – Angular

  1. Andrew says:

    i got error:

    ERROR in Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 15:25 in the original .ts file), resolving symbol getToken in c:/sowtware/Iintelijidea/JAVA/jee/github/jwt-angular-javaee/src/main/webapp/angular-demo/src/app/app.module.ts, resolving symbol AppModule in c:/sowtware/Iintelijidea/JAVA/jee/github/jwt-angular-javaee/src/main/webapp/angular-demo/src/app/app.module.ts, resolving symbol AppModule in c:/sowtware/Iintelijidea/JAVA/jee/github/jwt-angular-javaee/src/main/webapp/angular-demo/src/app/app.module.ts, resolving symbol AppModule in c:/sowtware/Iintelijidea/JAVA/jee/github/jwt-angular-javaee/src/main/webapp/angular-demo/src/app/app.module.t

    • Dominik Mathmann says:

      It was a problem with the AoT compiler which do not support lambda constants as configuration parameter. See GIT fix (8bf1d8a)

  2. Bernd says:

    Sorry, but what do I need to do to compile/transpile the angular frontend.
    And where do I need to deploy the whole war (I assume). Into any JEE-Server?

    • Dominik Mathmann says:

      For the demo project we choose a little bit unusual architecture. The angular project is here part of the java ee project (src/main/webapp/anguar-demo).

      If you want to deploy the demo as one WAR-file, you have to build and run the demo project with the following steps:

      Build the angular app, go to src/main/webapp/angular-demo and run:

      ng build –base-href .
      generates the angular application to dist-folder
      (you need npm and angular-cli installed)

      Run a maven build in the web application

      deploy the WAR-file to any java ee webserver

      Go to http://localhost:8080/angular-jwt-1.0-SNAPSHOT/angular-demo/dist/

      Please keep in mind: this project architecture is not a good practice for real applications. Normally you whould have 2 projects, one for the backend (deployed on a java ee server) and one project for the frontend (can be deployed on every web server, of course on a java ee servre as well).

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

w

Verbinde mit %s

%d Bloggern gefällt das: