ntgCleaner
ntgCleaner

Reputation: 5985

Angular 4 w/ AngularFire 2 and Auth Guard

I have started creating a simple app that has a pre-login and post-login section. I'm using FireBase (with AngularFire2) as my authentication provider and I'd like to "Guard" the post-login pages using canActivate() in an auth guard service.

My problem is, I don't know the order or placement of each piece of code. I've simplified what I have below:

app.component.ts

constructor(private auth: Authentication) {
    this.auth.subscribe();
}

authentication.ts

export class Authentication {

    state: Observable<firebase.User>;
    user: any;
    isLoggedIn: boolean;

    constructor(private afAuth: AngularFireAuth, private router: Router) {
        this.state = afAuth.authState;
    }

    subscribe() {
        this.state.subscribe((auth) => {
            if(auth) {
                this.user = auth;
                console.log(this.user);
                this.isLoggedIn = true;
                return true;
            } else {
                this.isLoggedIn = false;
                return false;
            }
        });
    }

    login() {
        this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
    }

    logout() {
        this.afAuth.auth.signOut();
    }
}

auth-guard.service.ts

export class AuthGuard implements CanActivate {

    constructor(private auth: Authentication, private router: Router) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let url: string = state.url;
        return this.checkLogin(url);
    }

    checkLogin(url: string): boolean {
        if(this.auth.isLoggedIn) {
            console.log("Can Activate True");
            return true;
        } else {
            console.log("Can Activate False");
            return false;
        }
    }
}

Right now it's pretty much working. When I start fresh, I get a screen with all of my links on the top of the screen, a login and a logout button. When I click on the links at the top of the screen, I get the console.log saying "Can Activate False", which is perfect. I'm not logged in yet.

When I log in, then try the links again, I get the "Can Activate True" which is also perfect.

When I log out again, and without refreshing, I try to click on the links above and I don't get any console.log back.

I feel like something is wrong with my subscribe or just everything in general. What could I be doing wrong?

Upvotes: 0

Views: 3461

Answers (2)

braunpa
braunpa

Reputation: 116

You can use the AngularFireAuthGuard for that case.

Add the lines below to your routing.module.ts:

const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['login']);

    path: '',
    component: UserDashboardComponent,
    //data: { title: 'user.dashboard' },
    canActivate: [AngularFireAuthGuard],
    data: {authGuardPipe: redirectUnauthorizedToLogin}

This code-snipped will do a redirect if the User is not authenticated. And furthermore its easy to implement.

Upvotes: 0

Robin Dijkhof
Robin Dijkhof

Reputation: 19278

Try this:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
  return this.af.authState.map(auth => {
    if (isNullOrUndefined(auth)) {
      this.router.navigate(['/login']);
      return false;
    } else {
      return true;
    }
  });
}

It is much easier. No messing around with aync and sync stuff.

Upvotes: 1

Related Questions