Kert
Kert

Reputation: 101

Angular 4 navigate to landingpage in case of error 401

I have an Angular 4 app with two modules: guest and user. When not logged in and trying to navigate to .../user it just logs an error in console, but I can't seem to find the file that handles the navigation. Since it's just an error then app-routing.module.ts doesn't catch it. What I have in app-routing.module.ts:

const appRoutes: Routes = [
    { path: '', component: LoadingComponent, resolve: { RoleResolver } },
    { path: 'user', loadChildren: 'app/ROLE_USER/user.module#UserModule', canActivate: [AuthGuard] },
    { path: '**', component: InvalidRequestComponent }
];

Is there any way to catch the 401 error and send the user to .../guest? Inside the user-routing.module.ts file is a bunch of different routes, but nothing about an invalid request. Where to catch this error?

//E: I did, what @charsi suggested and it does redirect to .../guest when user is not allowed to go to .../user, but when logging in, it just gets stuck. I've modified his code to my needs.

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { DataService } from '../../ROLE_GUEST/services/data.service';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor (private dataService: DataService, private router: Router) {}
  canActivate(
      route: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
  ): any {
      this.dataService.getRole().subscribe(s => {
          switch ( s.role ) {
              case 'ROLE_USER':
                  return true;
              case 'ROLE_ANON:':
              default:
                  this.router.navigate(['/guest']);
                  return false;
          }
      });
  }
}

Upvotes: 0

Views: 1826

Answers (2)

charsi
charsi

Reputation: 3847

Add a canActivate to the routes you want to protect. And then implement an auth guard.

CanActivate

{ path: 'user', component: UserComponent, canActivate: [AuthGuard] },
{ path: 'guest', component: LoginFormComponent },
{ path: '**', redirectTo: 'login' }

--

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from '../_services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor (private auth: AuthService, private router: Router){}
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {
      this.dataService.getRole().subscribe(s => {
        switch ( s.role ) {
          case 'ROLE_USER':
            return true;
          case 'ROLE_ANON:':
          default:
            this.router.navigate(['/guest']);
            return false;
        }
    });
  }
}

Upvotes: 2

Hasan Fathi
Hasan Fathi

Reputation: 6106

You should create this route in router module:

{ path: 'guest', component: GuestComponent }

and your http request catch redirect to this:

private SendRequest(Url: string, Params: HttpParams): Observable<Any> {
let header: HttpHeaders = new HttpHeaders();
header = header.append('Content-Type', 'application/json');
header = header.append('Accept', 'application/json');

return this._http.get(Url, { params: Params, headers: header })
    .map((response: Response) => {
    }
    ).catch((error: any, caught) => {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    this.router.navigate(['/guest']);
                }
            } 
        });

}

Upvotes: 0

Related Questions