Reputation: 735
Service:
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { Router } from '@angular/router';
import { AngularFireAuth } from 'angularfire2/auth';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, public af: AngularFireAuth) { }
canActivate() {
this.af.authState.subscribe(res => {
if (res && res.uid) {
this.router.navigate(['/dashboard']);
} else {
// Prevent user from accessing any route other than /login or /register.
}
});
return true;
}
}
Router Module:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth-guard.service';
import { LoginComponent } from 'app/login/login.component';
import { RegisterComponent } from 'app/register/register.component';
import { DashboardComponent } from 'app/dashboard/dashboard.component';
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent, canActivate:[AuthGuard] },
{ path: 'register', component: RegisterComponent, canActivate:[AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate:[AuthGuard] },
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: '**', redirectTo: '/login', pathMatch: 'full' }
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule {}
What the canActivate function does is redirect the user if they are logged in or not. I have the guard attached to the routes in my router module, but I'm having trouble figuring out the correct logic for the next step:
If the user is not logged in, they should not be able to access any route other than /login or /register. Of course I could add this.router.navigate(['/login'])
in the else statement, but then that makes /register non-accessible.
Any insight is appreciated, thanks.
Upvotes: 0
Views: 1136
Reputation: 60567
You should only use the AuthGuard for routes, that need to be protected, which in your case seems to be the dashboard only. The canActivate
reads like: "This given AuthGuard can activate this route, if it returns true." instead of "This route can activate another route." So you could do as follows:
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate:[AuthGuard] },
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: '**', redirectTo: '/dashboard', pathMatch: 'full' }
];
@Injectable()
export class AuthGuard implements CanActivate {
private isLoggedIn = false;
constructor(private router: Router, public af: AngularFireAuth) {
af.authState.subscribe(res => this.isLoggedIn = res && res.uid);
}
canActivate() {
if (!this.isLoggedIn) {
this.router.navigate(['/login']);
return false;
} else {
return true;
}
}
}
With this, dashboard won't be accessible and redirect to /login when not logged in. You could have a link from the LoginComponent to the RegisterComponent, so it becomes reachable.
I presume that you have a LoginService? The service could redirect to the dashboard route, when the login was successful.
More information can be found here: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
Upvotes: 2