angulartypescriptauth-guard

AuthGuard not working properly in Angular


In My Application I am redirecting to the Home Page on successful login ,

      <form (ngSubmit)="onLogin()" name="loginForm" [formGroup]="loginForm">
        <div class="userInput">
          <mat-form-field class="full-width" appearance="outline">
            <mat-label>UserID</mat-label>
            <input
              formControlName="name" matInput placeholder="Enter User ID" required/>
            <mat-error *ngIf="!loginForm.controls['name'].valid">
                UserID is required
            </mat-error>
          </mat-form-field>
        </div>
        <div>
          <span>
            <a class="text-link" class="aLink" routerLink="/auth/forgot-password">Forgot Password?</a>
          </span>
          <mat-form-field class="full-width" appearance="outline">
            <mat-label>Password</mat-label>
            <input formControlName="password" matInput [type]=" hide ? 'password' : 'text'" required />
            <button  mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide Password'"
            [attr.aria-pressed]="hide">
            <mat-icon>
                {{hide ? 'visibility_off' : 'visibility'}}
            </mat-icon>
        </button>
        <mat-error *ngIf="!loginForm.controls['password'].valid">
            Password is required
          </mat-error>
        </mat-form-field>
        </div>
        <button mat-flat-button style="background-color: #16bca8">Login</button>
</form>

Above is my login.component.html

redirecting(){
    this.userService.logIn();
    const observer= {
        next: (x:any) => {console.log(x)}, 
        error: (err: any) => {console.log(err.error)}
    }
    this.http.get(this.url,{responseType: 'text' ,withCredentials: true}).subscribe(observer);
    
    this.router.navigate(['home']);
  }

  onLogin() {
    let body = {
      "username": username,
      "password": password
    }
    const observer = {
      next: (x: any) => {console.log(x);this.redirecting()}, 
      error: (err: any) => {console.log(err.error)}, 
      complete: () => console.log('Observer got a complete notification'),
    }
    this.http.post(url, body, { responseType: 'text', withCredentials: true }).subscribe(observer);
  }

Above is my login.component.ts

ngOnInit() {
        this.isLoggedIn = localStorage.getItem("loggedin") === "true";
    }
    loggedIn():boolean {
        return this.isLoggedIn || this.isRegistered;
    }
    logIn() {
        this.isLoggedIn = true;
        localStorage.setItem("loggedin", "true");
    }

Above is the service which I am using

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree 
    {
    
        if (this.userService.loggedIn()) {
            console.log("Authorized");
            return true;
        } else {
            console.log("Not Auhtorized");
            this.router.navigate(['login']);
            return false;
        }
    }

Above is the auth.guard.ts

{ path: '',   redirectTo: '/home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
    { path: 'professor', component: ProfessorComponent },
    { path: 'login', component: LoginComponent },
}

I have added the above routes in application.

Any help would be appreciated. Thank You!


Solution

  • Your AuthGuard is ok. Sure it can be written better, but it is working. But in refresh the service is returning false for the loggedIn().

    On your service you're calling onInit to check local storage if logged in.

    ngOnInit() {
     this.isLoggedIn = localStorage.getItem("loggedin") === "true";
    }
    

    OnInit() will not work for services please see Lifecycle hooks

    Why don't you just get the logged info from local storage in the function instead? (Or use constructor instead on OnInit)

    loggedIn():boolean {
     return localStorage.getItem("loggedin") === "true";
    }
    
    
    logIn() {
     localStorage.setItem("loggedin", "true");
    }