Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the Access Guard and Secure the Customers Route #18

Open
hazartilirot opened this issue May 19, 2023 · 0 comments
Open

Implement the Access Guard and Secure the Customers Route #18

hazartilirot opened this issue May 19, 2023 · 0 comments

Comments

@hazartilirot
Copy link

Here would be a tricky one.

Open your guard directory in a terminal window, and enter the following:
ng generate guard Access

In the app.module.ts file, in the bottom, paste the code:

export class AppModule {
    constructor(private injector: Injector) {
        AppInjector = this.injector;
    }
}

Right after all imports and before @NgModule paste the piece:
export let AppInjector: Injector;

you would also need to import Injector
import { Injector, NgModule } from "@angular/core";

I leave my complete authentication.service.ts,

import { Inject, Injectable, Injector } from "@angular/core";

import { AuthenticationRequest } from "../../models/authentication-request";
import { AuthenticationResponse } from "../../models/authentication-response";
import { Observable } from "rxjs";
import { HttpClient } from "@angular/common/http";
import { JwtHelperService } from "@auth0/angular-jwt";
import { Router } from "@angular/router";

@Injectable({
    providedIn: "root"
})
export class AuthenticationService {

    constructor(
        private http: HttpClient,
        private router: Router,
    ) {
    }

    authenticate(credentialsForLogin: AuthenticationRequest): Observable<AuthenticationResponse> {
        return this.http.post<AuthenticationResponse>(
            "http://localhost:8080/api/v1/auth/login",
            credentialsForLogin
        );
    }

    setSession(authenticationResponse: AuthenticationResponse): void {
        localStorage.setItem("userId", `${authenticationResponse.customerDto.id}`);
        localStorage.setItem("token", authenticationResponse.token);
    }

    isSessionValid(): boolean {
        const userId: number = Number(localStorage.getItem("userId"));
        const token: string = localStorage.getItem("token");

        if (this.isLocalStorageInfringed(userId, token) || this.isTokenExpired(token)) {
            this.logout();
            return false;
        }
        return true;
    }

    private logout(): void {
        localStorage.clear();
        this.router.navigate(["login"])
    }

    private isTokenExpired(token: string): boolean {
        return new JwtHelperService().isTokenExpired(token);
    }

    private isLocalStorageInfringed(userId: number, token: string): boolean {
        return !userId || !token;
    }
}

in login.component.ts insert in constructor

if (authenticationService.isSessionValid()) {
            router.navigate(["customer"]);
        }

the login function in the same file has setSeesion method you need to place

next: authenticationResponse => {
                    this.authenticationService.setSession(authenticationResponse);
                    this.router.navigate(["customer"]);
                },

Now the Guard itself.... I just don't know how to create an instance in the method... It complains on httpClient, then router.... so I've found a solution relying on injection

import { CanActivateFn } from "@angular/router";
import { AuthenticationService } from "../authentication/authentication.service";
import { AppInjector } from "../../app.module";

export const accessGuard: CanActivateFn = (route, state) => {
    return AppInjector.get(AuthenticationService).isSessionValid()
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant