Added authguard for protected routes

This commit is contained in:
Igor Hrenowitsch Propisnov 2024-07-18 21:05:28 +02:00
parent 3362115ba6
commit 9fea964cf7
4 changed files with 67 additions and 17 deletions

View File

@ -1,5 +1,7 @@
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import { AuthGuard } from './shared/guards';
const simpleLayoutRoutes: Routes = [ const simpleLayoutRoutes: Routes = [
{ {
path: '', path: '',
@ -43,6 +45,7 @@ export const routes: Routes = [
import('./layout/main-layout/layout.component').then( import('./layout/main-layout/layout.component').then(
(m) => m.LayoutComponent (m) => m.LayoutComponent
), ),
canActivate: [AuthGuard],
children: [ children: [
{ {
path: '', path: '',

View File

@ -0,0 +1,22 @@
import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { map, take } from 'rxjs';
import { AuthService } from '../service';
export const AuthGuard: CanActivateFn = () => {
const authService: AuthService = inject(AuthService);
const router: Router = inject(Router);
return authService.status().pipe(
take(1),
map((response) => {
if (response.success) {
return true;
} else {
return router.createUrlTree(['/welcome']);
}
})
);
};

View File

@ -0,0 +1 @@
export * from './auth.guard';

View File

@ -1,45 +1,69 @@
import { Injectable } from '@angular/core'; import { Injectable, WritableSignal, signal } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { BehaviorSubject, Observable } from 'rxjs'; import { Observable, of, throwError } from 'rxjs';
import { catchError, shareReplay, tap } from 'rxjs/operators';
import { import {
AuthenticationApiService,
SigninResponseDtoApiModel, SigninResponseDtoApiModel,
SuccessDtoApiModel,
UserCredentialsDtoApiModel, UserCredentialsDtoApiModel,
} from '../../api'; } from '../../api';
import { AuthenticationApiService } from '../../api/api/authentication.api.service';
type SuccessResponse = {
success: boolean;
};
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AuthService { export class AuthService {
public isAuthenticated$: BehaviorSubject<boolean> = public isAuthenticatedSignal: WritableSignal<boolean> = signal(false);
new BehaviorSubject<boolean>(false); public isAuthenticated$: Observable<boolean> = toObservable(
this.isAuthenticatedSignal
);
private statusCheck$: Observable<SuccessDtoApiModel>;
public constructor( public constructor(
private readonly authenticationApiService: AuthenticationApiService private readonly authenticationApiService: AuthenticationApiService
) {} ) {
this.statusCheck$ = this.initializeStatusCheck();
}
public signup( public signup(
credentials: UserCredentialsDtoApiModel credentials: UserCredentialsDtoApiModel
): Observable<SuccessResponse> { ): Observable<SuccessDtoApiModel> {
return this.authenticationApiService.authControllerSignup(credentials); return this.authenticationApiService
.authControllerSignup(credentials)
.pipe(tap(() => this.isAuthenticatedSignal.set(true)));
} }
public signin( public signin(
credentials: UserCredentialsDtoApiModel credentials: UserCredentialsDtoApiModel
): Observable<SigninResponseDtoApiModel> { ): Observable<SigninResponseDtoApiModel> {
return this.authenticationApiService.authControllerSignin(credentials); return this.authenticationApiService
.authControllerSignin(credentials)
.pipe(tap(() => this.isAuthenticatedSignal.set(true)));
} }
public signout(): Observable<SuccessResponse> { public signout(): Observable<SuccessDtoApiModel> {
return this.authenticationApiService.authControllerSignout(); return this.authenticationApiService
.authControllerSignout()
.pipe(tap(() => this.isAuthenticatedSignal.set(false)));
} }
public status(): Observable<SuccessResponse> { public status(): Observable<SuccessDtoApiModel> {
return this.authenticationApiService.authControllerStatus(); if (this.isAuthenticatedSignal()) {
return of({ success: true });
}
return this.statusCheck$;
}
private initializeStatusCheck(): Observable<SuccessDtoApiModel> {
return this.authenticationApiService.authControllerStatus().pipe(
tap((response) => this.isAuthenticatedSignal.set(response.success)),
catchError((error) => {
this.isAuthenticatedSignal.set(false);
return throwError(() => error);
}),
shareReplay(1)
);
} }
} }