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)
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:
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.
4 Kommentare. Hinterlasse eine Antwort
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
It was a problem with the AoT compiler which do not support lambda constants as configuration parameter. See GIT fix (8bf1d8a)
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?
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).