2

I've added a login feature to my app. When someone navigates to the URL with a blank path(http://example.com), I want the HomeComponent to show up which will activate the AuthGuard, but keep the URL path blank. I am still testing locally, so that may be the issue? I'm not sure.

Whats happening now - when I navigate to localhost:3000/ I get nothing, just a blank screen. When I navigate to localhost:3000/home, I get my HomeComponent to show with no issue but I would like the HomeComponent to be called when the URL is localhost:3000/.

Here's my app.module file - I'm not really sure what other files I need to post since the issue lies with the routing. Like I said, I can get to all of the other components by typing the path. But for Home, I do not want to have to type the path.

app.module.ts

   import { NgModule } from '@angular/core';
   import { BrowserModule } from '@angular/platform-browser';
   import { FormsModule, ReactiveFormsModule } from '@angular/forms';
   import { HttpModule } from '@angular/http';
   import { RouterModule, Routes } from '@angular/router';

   import { AppComponent }  from './app.component';

   import { HomeComponent } from './home/home.component';

   import { LoginComponent } from './login/login.component';
   import { AlertService } from './login/services/alert.service';
   import { AlertComponent } from './directives/alert.component';
   import { AuthenticationService } from './login/services/authentication.service';
   import { AuthGuard } from './guards/auth.guard';

@NgModule({
imports: [ 
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    RouterModule.forRoot([

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

      ]) 
],
providers: [
    AuthGuard,
    AlertService,
    AuthenticationService
],
declarations: [ 
    LoginComponent,
    AlertComponent,
    HomeComponent,
    AppComponent,
],
bootstrap: [ AppComponent ]
})
export class AppModule { }

I have also tried setting my default route like this, but still same issue:

{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard] },

My base href is set to:

<base href="/" />

I'm not receiving any errors and my console looks clean. Again, I can navigate just fine if I add "/home" to the end of my URL, but I want a blank URL path to show the HomeComponent with AuthGuard.

I've been through documentation and other questions but nothing has worked for me. I'm not sure what I'm missing. Any help would be greatly appreciated. Let me know if there are any other code snippets I need to post. Thanks in advance.

Joe Chaiet
  • 23
  • 1
  • 4
  • Possible duplicate of [Angular 2 AuthGuard Service with redirect?](https://stackoverflow.com/questions/39002288/angular-2-authguard-service-with-redirect) – 0mpurdy Jul 25 '17 at 13:55
  • @joe, are you calling `{path: '', pathMatch: 'full'}` again somewhere else? I had the same issue and removing the second declaration of the path fixed the issue for me. – teddybear Nov 09 '17 at 23:01

3 Answers3

1

The routing in Angular 2 depends, like in many other frameworks, on the order of your routes.

Your first route with path: '' matches each request and is going to be executed. But if your user is not authorized the guard is blocking the request.

It's recommended to sort the routes from more specific to less specific like this:

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

With this configuration a request to localhost:3000/ would be catched from the last route and redirect to /home. With the route '**' you would catch every request that is not covered in your route configuration and redirect it to / which would then redirect to home.

I don't know if it matters, but your base is set to <base href='/' />. The documentation of Angular says that it must be <base href='/'>.

Ma Kobi
  • 888
  • 6
  • 21
0

in my case this code bellow work well.

@Injectable()
export class LoggedInGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {


    const isLoggedIn = this.authService.isLoggedIn();
    if (!isLoggedIn) {
        const bool = confirm('Dany access!\nCan i redirect u to login page?');

        return await (bool) ? this.router.navigateByUrl('/login') : this.router.navigateByUrl('/') ;
    }
    return isLoggedIn;
  }
}

i saw this code in an Ionic project and until now i had no more problem with redirect.

-1

If you look at the Configuration section of the routing docs

You can see that you are missing a / in your second attempt. You should also remove the AuthGuard from your empty route.

{ 
  path: '',
  redirectTo: '/home',
  pathMatch: 'full'
}

You may also need to update your AuthGuard to include what is described in this answer as shown below

@Injectable()

export class AuthGuard implements CanActivate {

  auth: any = {};

  constructor(private authService: AuthService, private router: Router) {

  }

  canActivate() {
    if (/*user is logged in*/) {
      return true;
    }
    else {
      this.router.navigate(['/login']);
    }
    return false;
  }
}
0mpurdy
  • 3,198
  • 1
  • 19
  • 28
  • @MaKobi sorry I commented on your answer before seeing your comment here, pathMatch is set to true so it won't match the path unless it **completely** matches it so where it comes in the order doesn't matter. But you're right - best practice would dictate that you order it correctly anyway – 0mpurdy Jul 25 '17 at 14:15
  • I dont need to navigate from AuthGuard because if the user is logged in they are automatically redirected to empty path - which *should* load /home, but thats where my issue it - i cant get an empty path to load anything. If a user who is NOT logged in tries to navigate straight to /home, AuthGuard will redirect them to /login and also store the URL path. So when they login they are redirected to where they wanted to go (/home or any other path they used). – Joe Chaiet Jul 25 '17 at 14:40
  • Router redirects will not occur if they are navigated to by a Router Guard, you should instead navigate using the router in the RouterGuard itself directly to the route that you want to eventually route to. Unless I have perhaps misunderstood your question - I will try and make a live example - unless you've got a plunker I could try? – 0mpurdy Jul 25 '17 at 14:42
  • @JoeChaiet Ok I've had a minute to read your question more carefully, why do you need the `AuthGuard` on the `''` path? why not allow it to redirect to `/home` which has it's own `AuthGuard`? Would you get the behaviour you want just by removing it? If that's what you mean I'll update my answer – 0mpurdy Jul 25 '17 at 15:55