Improve performanace of the readme #8
144
README.md
144
README.md
@ -1,144 +0,0 @@
|
|||||||
# Starter für das LF10 Projekt
|
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
* Docker https://docs.docker.com/get-docker/
|
|
||||||
* Docker compose (bei Windows und Mac schon in Docker enthalten) https://docs.docker.com/compose/install/
|
|
||||||
|
|
||||||
|
|
||||||
### Abhängigkeiten starten (Postgres, EmployeeBackend)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up
|
|
||||||
```
|
|
||||||
|
|
||||||
Achtung: Der Docker-Container läuft dauerhaft! Wenn er nicht mehr benötigt wird, solltest du ihn stoppen.
|
|
||||||
|
|
||||||
### Abhängigkeiten stoppen
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose down
|
|
||||||
```
|
|
||||||
|
|
||||||
### Postgres Datenbank wipen, z.B. bei Problemen
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose down
|
|
||||||
docker volume rm docker_employee_postgres_data
|
|
||||||
docker compose up
|
|
||||||
```
|
|
||||||
|
|
||||||
## Swagger des Backends
|
|
||||||
|
|
||||||
```
|
|
||||||
http://localhost:8089/swagger
|
|
||||||
```
|
|
||||||
|
|
||||||
# Postgres
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Intellij-Ansicht für Postgres Datenbank einrichten (geht nicht in Webstorm!)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
1. Lasse den Docker-Container mit den Abhängigkeiten laufen
|
|
||||||
2. rechts im Fenster den Reiter Database öffnen
|
|
||||||
3. In der Database-Symbolleiste auf das Datenbanksymbol mit dem Schlüssel klicken
|
|
||||||
4. auf das Pluszeichen klicken
|
|
||||||
5. Datasource from URL auswählen
|
|
||||||
6. URL der DB einfügen (jdbc:postgresql://postgres-employee:5432/employee_db) und PostgreSQL-Treiber auswählen, mit OK bestätigen
|
|
||||||
7. Username lf10_starter und Passwort secret eintragen (siehe application.properties), mit Apply bestätigen
|
|
||||||
8. im Reiter Schemas alle Häkchen entfernen und lediglich vor lf10_starter_db und public Häkchen setzen
|
|
||||||
9. mit Apply und ok bestätigen
|
|
||||||
```
|
|
||||||
|
|
||||||
# Keycloak
|
|
||||||
|
|
||||||
## Keycloak Token
|
|
||||||
|
|
||||||
1. Auf der Projektebene [getBearerToken.http](./getBearerToken.http) öffnen.
|
|
||||||
2. Neben der Request auf den grünen Pfeil drücken
|
|
||||||
3. Aus dem Reponse das access_token kopieren
|
|
||||||
|
|
||||||
## Keycloak-Integration
|
|
||||||
|
|
||||||
Das Login soll als Single Sign On für alle Applikationen der HiTec GmbH implementiert werden. Dabei soll der Benutzer beim Aufruf von http://localhost:4200
|
|
||||||
zunächst auf eine Seite im Firmendesign mit Informationen über die verschiedenen Anwendungen der HiTec GmbH geleitet werden. Auf dieser Seite
|
|
||||||
befindet sich ein Link zum Employee-Management-Service. Klickt der Benutzer auf diesen Link und ist noch nicht angemeldet, wird er zum Login des bereits
|
|
||||||
existierenden Keycloak-Service weitergeleitet, loggt sich dort ein und wird zum Frontend des Employee Management Services zurückgeleitet. Nach dem Logout
|
|
||||||
wird der Benutzer wieder zur Startseite mit den Informationen über die Anwendungen der HiTec GmbH zurückgeleitet.
|
|
||||||
Für die Keycloak-Integration benötigst du die Bibliotheken keycloak-angular und keycloak-js. Beide sind im Starter-Projekt schon enthalten (siehe package.json),
|
|
||||||
brauchen also nicht mehr per npm install hinzugefügt werden. Eine Dokumentation der Bibliotheken findest du hier https://www.npmjs.com/package/keycloak-angular.
|
|
||||||
|
|
||||||
Um den vorhandenen Keycloak-Service in deine Anwendung integrieren zu können, benötigst du folgende Informationen:
|
|
||||||
|
|
||||||
URL, über der der Service zu erreichen ist: https://keycloak.szut.dev/auth,
|
|
||||||
der Realm hat die Bezeichnung: szut,
|
|
||||||
die ClientId deines Angular Frontends lautet: employee-management-service-frontend
|
|
||||||
|
|
||||||
Hier ein Beispiel einer app.config.ts mit der Konfiguration für Keycloak. Mit dem KeycloakService, der hier definiert wird, kannst du in einem AuthGuard z.B. feststellen, ob der Benutzer eingeloggt ist oder nicht oder ihn mit keycloakService.login() zum Login weiterleiten.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import {APP_INITIALIZER, ApplicationConfig} from '@angular/core';
|
|
||||||
import { provideRouter } from '@angular/router';
|
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
|
||||||
import {KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService} from "keycloak-angular";
|
|
||||||
import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from "@angular/common/http";
|
|
||||||
|
|
||||||
export const initializeKeycloak = (keycloak: KeycloakService) => async () =>
|
|
||||||
keycloak.init({
|
|
||||||
config: {
|
|
||||||
url: 'KEYCLOAK_URL',
|
|
||||||
realm: 'REALM',
|
|
||||||
clientId: 'CLIENT_ID',
|
|
||||||
},
|
|
||||||
loadUserProfileAtStartUp: true,
|
|
||||||
initOptions: {
|
|
||||||
onLoad: 'check-sso',
|
|
||||||
silentCheckSsoRedirectUri:
|
|
||||||
window.location.origin + '/silent-check-sso.html',
|
|
||||||
checkLoginIframe: false,
|
|
||||||
redirectUri: 'http://localhost:4200',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function initializeApp(keycloak: KeycloakService): () => Promise<boolean> {
|
|
||||||
return () => initializeKeycloak(keycloak)();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
|
||||||
providers: [provideRouter(routes),
|
|
||||||
KeycloakAngularModule,
|
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
useFactory: initializeApp,
|
|
||||||
multi: true,
|
|
||||||
deps: [KeycloakService]
|
|
||||||
},
|
|
||||||
KeycloakService,
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
{
|
|
||||||
provide: HTTP_INTERCEPTORS,
|
|
||||||
useClass: KeycloakBearerInterceptor,
|
|
||||||
multi: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Der Benutzer, mit dem ihr eure Integration testen könnt, hat den Benutzernamen user und das Passwort test. Die einzige Rolle heißt user.
|
|
||||||
|
|
||||||
Des Weiteren ist der Client mit der Bezeichnung employee-management-service-frontend wie folgt konfiguriert:
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
# Bugs
|
|
||||||
|
|
||||||
Trage hier die Features ein, die nicht funktionieren. Beschreibe den jeweiligen Fehler.
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
|||||||
"@angular/platform-browser": "^19.0.4",
|
"@angular/platform-browser": "^19.0.4",
|
||||||
"@angular/platform-browser-dynamic": "^19.0.4",
|
"@angular/platform-browser-dynamic": "^19.0.4",
|
||||||
"@angular/router": "^19.0.4",
|
"@angular/router": "^19.0.4",
|
||||||
|
"keycloak-angular": "^16.1.0",
|
||||||
"rxjs": "~7.8.1",
|
"rxjs": "~7.8.1",
|
||||||
"tailwind": "4.0.0",
|
"tailwind": "4.0.0",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
@ -38,4 +39,4 @@
|
|||||||
"karma-jasmine-html-reporter": "~2.1.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"typescript": "~5.5.4"
|
"typescript": "~5.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
public/silent-check-sso.html
Normal file
7
public/silent-check-sso.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
parent.postMessage(location.href, location.origin);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,2 +1,2 @@
|
|||||||
<app-employee-list></app-employee-list>
|
<router-outlet></router-outlet>
|
||||||
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [AppComponent],
|
|
||||||
}).compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create the app', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have the 'lf10StarterNew' title`, () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.componentInstance;
|
|
||||||
expect(app.title).toEqual('lf10StarterNew');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render title', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.nativeElement as HTMLElement;
|
|
||||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, lf10StarterNew');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,13 +1,13 @@
|
|||||||
import { Component } from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import {RouterOutlet} from '@angular/router';
|
||||||
import {EmployeeListComponent} from "./employee-list/employee-list.component";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [CommonModule, EmployeeListComponent],
|
imports: [CommonModule, RouterOutlet],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.css'
|
standalone: true,
|
||||||
|
styleUrl: './app.component.css'
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'lf10StarterNew';
|
title = 'lf10StarterNew';
|
||||||
|
@ -1,10 +1,50 @@
|
|||||||
import { ApplicationConfig } from '@angular/core';
|
import {APP_INITIALIZER, ApplicationConfig} from '@angular/core';
|
||||||
import { provideRouter } from '@angular/router';
|
import {provideRouter} from '@angular/router';
|
||||||
|
import {KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService} from "keycloak-angular";
|
||||||
|
import {routes} from './app.routes';
|
||||||
|
import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from "@angular/common/http";
|
||||||
|
import {provideAnimationsAsync} from '@angular/platform-browser/animations/async';
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
export const initializeKeycloak = (keycloak: KeycloakService) => async () =>
|
||||||
import {provideHttpClient, withInterceptorsFromDi} from "@angular/common/http";
|
keycloak.init({
|
||||||
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
config: {
|
||||||
|
url: 'https://keycloak.szut.dev/auth',
|
||||||
|
realm: 'szut',
|
||||||
|
clientId: 'employee-management-service-frontend',
|
||||||
|
},
|
||||||
|
loadUserProfileAtStartUp: true,
|
||||||
|
initOptions: {
|
||||||
|
onLoad: 'check-sso',
|
||||||
|
silentCheckSsoRedirectUri:
|
||||||
|
window.location.origin + '/silent-check-sso.html',
|
||||||
|
checkLoginIframe: false,
|
||||||
|
redirectUri: 'http://localhost:4200',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function initializeApp(keycloak: KeycloakService): () => Promise<boolean> {
|
||||||
|
return () => initializeKeycloak(keycloak)();
|
||||||
|
}
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [provideRouter(routes), provideHttpClient(withInterceptorsFromDi()), provideAnimationsAsync()]
|
providers: [
|
||||||
|
provideRouter(routes),
|
||||||
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
|
provideAnimationsAsync(),
|
||||||
|
KeycloakAngularModule,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
useFactory: initializeApp,
|
||||||
|
multi: true,
|
||||||
|
deps: [KeycloakService]
|
||||||
|
},
|
||||||
|
KeycloakService,
|
||||||
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
|
{
|
||||||
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
useClass: KeycloakBearerInterceptor,
|
||||||
|
multi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
import { Routes } from '@angular/router';
|
import {Routes} from '@angular/router';
|
||||||
|
import {EmployeeListComponent} from "./employee-list/employee-list.component";
|
||||||
|
import {LoginComponent} from "./login/login.component";
|
||||||
|
import {AuthGuardService} from "./services/auth-guard.service";
|
||||||
|
|
||||||
export const routes: Routes = [];
|
export const routes: Routes = [
|
||||||
|
{path: 'login', component: LoginComponent},
|
||||||
|
{path: '', component: EmployeeListComponent, canActivate: [AuthGuardService]},
|
||||||
|
{path: '**', redirectTo: ''}
|
||||||
|
];
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { EmployeeListComponent } from './employee-list.component';
|
|
||||||
|
|
||||||
describe('EmployeeListComponent', () => {
|
|
||||||
let component: EmployeeListComponent;
|
|
||||||
let fixture: ComponentFixture<EmployeeListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [EmployeeListComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(EmployeeListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -5,10 +5,11 @@ import {HttpClient, HttpHeaders} from "@angular/common/http";
|
|||||||
import {Employee} from "../Employee";
|
import {Employee} from "../Employee";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-employee-list',
|
selector: 'app-employee-list',
|
||||||
imports: [CommonModule],
|
imports: [CommonModule],
|
||||||
templateUrl: './employee-list.component.html',
|
templateUrl: './employee-list.component.html',
|
||||||
styleUrl: './employee-list.component.css'
|
standalone: true,
|
||||||
|
styleUrl: './employee-list.component.css'
|
||||||
})
|
})
|
||||||
export class EmployeeListComponent {
|
export class EmployeeListComponent {
|
||||||
bearer = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzUFQ0dldiNno5MnlQWk1EWnBqT1U0RjFVN0lwNi1ELUlqQWVGczJPbGU0In0.eyJleHAiOjE3MzM5MTQ5MjgsImlhdCI6MTczMzkxMTMyOCwianRpIjoiMjNhYzMwMmUtYmYxNS00OTRmLWJhYTItNjIzODllYWZkMmZhIiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5zenV0LmRldi9hdXRoL3JlYWxtcy9zenV0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjU1NDZjZDIxLTk4NTQtNDMyZi1hNDY3LTRkZTNlZWRmNTg4OSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImVtcGxveWVlLW1hbmFnZW1lbnQtc2VydmljZSIsInNlc3Npb25fc3RhdGUiOiI2ODdiMTEwYS00NTRjLTQwMzgtYjBkMS1kZDAzZGQ1N2JiNjEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDIwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsicHJvZHVjdF9vd25lciIsIm9mZmxpbmVfYWNjZXNzIiwiZGVmYXVsdC1yb2xlcy1zenV0IiwidW1hX2F1dGhvcml6YXRpb24iLCJ1c2VyIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIifQ.E5ir1Z-POpUU_jvTh8CzoMYO74qo_7uQXw7QQBUvXB2_37pT3_tutAq6sM4V5cNBu--fWar5bltlNcOAWd_7Kdb66Qc23i0RR9vPneoSduJAzoD8gtFbx8c7ltNR4pG-c6tdnkGhLLqM621DShaSlH8Shp-Z0-y4Iq3GFdQrAFH1CrRVYlW0qFv1EZsE9BmhW3hJwrR1S2IPiEN6MwhehLflLa_ZgLcF417ocIfK-6gbbRNAwXA-JajFVOZAEVXs-52Ta9Kb_EEQFpRsjXorfflmbizQmgrbhBUB7MTiPYIcRruZSYdfmjcE008PHnut52cTcVYEuOrUCUqY4VmhoQ';
|
bearer = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzUFQ0dldiNno5MnlQWk1EWnBqT1U0RjFVN0lwNi1ELUlqQWVGczJPbGU0In0.eyJleHAiOjE3MzM5MTQ5MjgsImlhdCI6MTczMzkxMTMyOCwianRpIjoiMjNhYzMwMmUtYmYxNS00OTRmLWJhYTItNjIzODllYWZkMmZhIiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5zenV0LmRldi9hdXRoL3JlYWxtcy9zenV0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjU1NDZjZDIxLTk4NTQtNDMyZi1hNDY3LTRkZTNlZWRmNTg4OSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImVtcGxveWVlLW1hbmFnZW1lbnQtc2VydmljZSIsInNlc3Npb25fc3RhdGUiOiI2ODdiMTEwYS00NTRjLTQwMzgtYjBkMS1kZDAzZGQ1N2JiNjEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDIwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsicHJvZHVjdF9vd25lciIsIm9mZmxpbmVfYWNjZXNzIiwiZGVmYXVsdC1yb2xlcy1zenV0IiwidW1hX2F1dGhvcml6YXRpb24iLCJ1c2VyIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIifQ.E5ir1Z-POpUU_jvTh8CzoMYO74qo_7uQXw7QQBUvXB2_37pT3_tutAq6sM4V5cNBu--fWar5bltlNcOAWd_7Kdb66Qc23i0RR9vPneoSduJAzoD8gtFbx8c7ltNR4pG-c6tdnkGhLLqM621DShaSlH8Shp-Z0-y4Iq3GFdQrAFH1CrRVYlW0qFv1EZsE9BmhW3hJwrR1S2IPiEN6MwhehLflLa_ZgLcF417ocIfK-6gbbRNAwXA-JajFVOZAEVXs-52Ta9Kb_EEQFpRsjXorfflmbizQmgrbhBUB7MTiPYIcRruZSYdfmjcE008PHnut52cTcVYEuOrUCUqY4VmhoQ';
|
||||||
|
0
src/app/login/login.component.css
Normal file
0
src/app/login/login.component.css
Normal file
1
src/app/login/login.component.html
Normal file
1
src/app/login/login.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<p>login works!</p>
|
12
src/app/login/login.component.ts
Normal file
12
src/app/login/login.component.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
imports: [],
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
standalone: true,
|
||||||
|
styleUrl: './login.component.css'
|
||||||
|
})
|
||||||
|
export class LoginComponent {
|
||||||
|
|
||||||
|
}
|
21
src/app/services/auth-guard.service.ts
Normal file
21
src/app/services/auth-guard.service.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {AuthService} from "./auth.service";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
import {KeycloakService} from "keycloak-angular";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthGuardService {
|
||||||
|
constructor(public auth: AuthService, public router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
canActivate(): boolean {
|
||||||
|
if (!this.auth.isAuthenticated()) {
|
||||||
|
this.router.navigate(['login']);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
19
src/app/services/auth.service.ts
Normal file
19
src/app/services/auth.service.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import {inject, Injectable} from '@angular/core';
|
||||||
|
import {KeycloakService} from "keycloak-angular";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthService {
|
||||||
|
private keycloakService = inject(KeycloakService);
|
||||||
|
|
||||||
|
public isAuthenticated(): boolean {
|
||||||
|
if (this.keycloakService.isLoggedIn()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.keycloakService.login();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user