@@ -1,6 +1,14 @@
|
|
1 |
<nav>
|
2 |
<a routerLink="/home" routerLinkActive="active" ariaCurrentWhenActive="page">Home</a>
|
3 |
<a routerLink="/books" routerLinkActive="active" ariaCurrentWhenActive="page">Books</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
</nav>
|
5 |
|
6 |
<main>
|
1 |
<nav>
|
2 |
<a routerLink="/home" routerLinkActive="active" ariaCurrentWhenActive="page">Home</a>
|
3 |
<a routerLink="/books" routerLinkActive="active" ariaCurrentWhenActive="page">Books</a>
|
4 |
+
<div class="actions">
|
5 |
+
<button class="green"
|
6 |
+
(click)="auth.login()"
|
7 |
+
*ngIf="!auth.isAuthenticated">Login</button>
|
8 |
+
<button class="red"
|
9 |
+
(click)="auth.logout()"
|
10 |
+
*ngIf="auth.isAuthenticated">Logout</button>
|
11 |
+
</div>
|
12 |
</nav>
|
13 |
|
14 |
<main>
|
@@ -1,8 +1,12 @@
|
|
1 |
import { Component } from '@angular/core';
|
2 |
|
|
|
|
|
3 |
@Component({
|
4 |
selector: 'bm-root',
|
5 |
templateUrl: './app.component.html',
|
6 |
styleUrls: ['./app.component.css']
|
7 |
})
|
8 |
-
export class AppComponent {
|
|
|
|
1 |
import { Component } from '@angular/core';
|
2 |
|
3 |
+
import { AuthService } from './shared/auth.service';
|
4 |
+
|
5 |
@Component({
|
6 |
selector: 'bm-root',
|
7 |
templateUrl: './app.component.html',
|
8 |
styleUrls: ['./app.component.css']
|
9 |
})
|
10 |
+
export class AppComponent {
|
11 |
+
constructor(public auth: AuthService) {}
|
12 |
+
}
|
@@ -1,5 +1,5 @@
|
|
1 |
import { NgModule } from '@angular/core';
|
2 |
-
import { HttpClientModule } from '@angular/common/http';
|
3 |
import { BrowserModule } from '@angular/platform-browser';
|
4 |
|
5 |
import { AppRoutingModule } from './app-routing.module';
|
@@ -7,6 +7,7 @@ import { AppComponent } from './app.component';
|
|
7 |
import { BooksModule } from './books/books.module';
|
8 |
import { HomeComponent } from './home/home.component';
|
9 |
import { SearchComponent } from './search/search.component';
|
|
|
10 |
|
11 |
@NgModule({
|
12 |
declarations: [
|
@@ -20,7 +21,13 @@ import { SearchComponent } from './search/search.component';
|
|
20 |
HttpClientModule,
|
21 |
BooksModule
|
22 |
],
|
23 |
-
providers: [
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
bootstrap: [AppComponent]
|
25 |
})
|
26 |
export class AppModule { }
|
1 |
import { NgModule } from '@angular/core';
|
2 |
+
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
3 |
import { BrowserModule } from '@angular/platform-browser';
|
4 |
|
5 |
import { AppRoutingModule } from './app-routing.module';
|
7 |
import { BooksModule } from './books/books.module';
|
8 |
import { HomeComponent } from './home/home.component';
|
9 |
import { SearchComponent } from './search/search.component';
|
10 |
+
import { AuthInterceptor } from './shared/auth.interceptor';
|
11 |
|
12 |
@NgModule({
|
13 |
declarations: [
|
21 |
HttpClientModule,
|
22 |
BooksModule
|
23 |
],
|
24 |
+
providers: [
|
25 |
+
{
|
26 |
+
provide: HTTP_INTERCEPTORS,
|
27 |
+
useClass: AuthInterceptor,
|
28 |
+
multi: true
|
29 |
+
}
|
30 |
+
],
|
31 |
bootstrap: [AppComponent]
|
32 |
})
|
33 |
export class AppModule { }
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { AuthInterceptor } from './auth.interceptor';
|
4 |
+
|
5 |
+
describe('AuthInterceptor', () => {
|
6 |
+
beforeEach(() => TestBed.configureTestingModule({
|
7 |
+
providers: [
|
8 |
+
AuthInterceptor
|
9 |
+
]
|
10 |
+
}));
|
11 |
+
|
12 |
+
it('should be created', () => {
|
13 |
+
const interceptor: AuthInterceptor = TestBed.inject(AuthInterceptor);
|
14 |
+
expect(interceptor).toBeTruthy();
|
15 |
+
});
|
16 |
+
});
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Injectable } from '@angular/core';
|
2 |
+
import {
|
3 |
+
HttpRequest,
|
4 |
+
HttpHandler,
|
5 |
+
HttpEvent,
|
6 |
+
HttpInterceptor
|
7 |
+
} from '@angular/common/http';
|
8 |
+
import { Observable } from 'rxjs';
|
9 |
+
import { AuthService } from './auth.service';
|
10 |
+
|
11 |
+
@Injectable()
|
12 |
+
export class AuthInterceptor implements HttpInterceptor {
|
13 |
+
|
14 |
+
constructor(private authService: AuthService) {}
|
15 |
+
|
16 |
+
intercept(
|
17 |
+
request: HttpRequest<unknown>,
|
18 |
+
next: HttpHandler
|
19 |
+
): Observable<HttpEvent<unknown>> {
|
20 |
+
const token = '1234567890';
|
21 |
+
|
22 |
+
if (this.authService.isAuthenticated) {
|
23 |
+
// Token in Header einfügen
|
24 |
+
const reqWithToken = request.clone({
|
25 |
+
setHeaders: {
|
26 |
+
Authorization: `Bearer ${token}`
|
27 |
+
}
|
28 |
+
});
|
29 |
+
|
30 |
+
return next.handle(reqWithToken);
|
31 |
+
} else {
|
32 |
+
// Request unverändert weitergeben
|
33 |
+
return next.handle(request);
|
34 |
+
}
|
35 |
+
}
|
36 |
+
}
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { AuthService } from './auth.service';
|
4 |
+
|
5 |
+
describe('AuthService', () => {
|
6 |
+
let service: AuthService;
|
7 |
+
|
8 |
+
beforeEach(() => {
|
9 |
+
TestBed.configureTestingModule({});
|
10 |
+
service = TestBed.inject(AuthService);
|
11 |
+
});
|
12 |
+
|
13 |
+
it('should be created', () => {
|
14 |
+
expect(service).toBeTruthy();
|
15 |
+
});
|
16 |
+
});
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Injectable } from '@angular/core';
|
2 |
+
import { BehaviorSubject } from 'rxjs';
|
3 |
+
|
4 |
+
@Injectable({
|
5 |
+
providedIn: 'root'
|
6 |
+
})
|
7 |
+
export class AuthService {
|
8 |
+
private _isAuthenticated$ = new BehaviorSubject(true);
|
9 |
+
readonly isAuthenticated$ = this._isAuthenticated$.asObservable();
|
10 |
+
|
11 |
+
get isAuthenticated() {
|
12 |
+
return this._isAuthenticated$.value;
|
13 |
+
}
|
14 |
+
|
15 |
+
login() {
|
16 |
+
this._isAuthenticated$.next(true);
|
17 |
+
}
|
18 |
+
|
19 |
+
logout() {
|
20 |
+
this._isAuthenticated$.next(false);
|
21 |
+
}
|
22 |
+
}
|