Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

typescript - Angular 2 AuthGuard + Firebase Auth

I'm trying to build an AuthGuard for Angular 2 routes using Firebase Auth.

This is the AuthGuard Service:

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

@Injectable()
export class AuthGuard implements CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.AuthService.loggedIn) { return true; }

    this.router.navigate(['login']);
    return false;
  }
}

And this is the AuthService which checks if the user's logged in and binds the result to the property 'loggedIn' in its constructor.

import { Injectable } from '@angular/core';
import { AngularFire } from 'angularfire2';
import { Router } from '@angular/router';

@Injectable()
export class AuthService {
loggedIn: boolean = false;

  constructor(
    public af: AngularFire,
    public router: Router) {
        af.auth.subscribe(user => {
            if(user){
                this.loggedIn = true;
            }
        });
    }
}

The problem here is obviously asynchrony. AuthGuard's canActivate() always returns a false value because the subscription doesn't receive the data in time to change 'loggedIn' to true.

What's the best practice to fix this?

EDIT:

Changed the AuthGuard to return an observable.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.af.auth.map((auth) => {
        if (!auth) {
          this.router.navigateByUrl('login');
          return false;
        }
        return true;
    });
  }

It kind of works since you don't get redirected to login... But the target AuthGuarded Component is not rendered.

Not sure if it has to do with my app.routes. This is the code for that part:

const routes: Routes = [
  { path: '', component: MainComponent, canActivate: [AuthGuard] },
  ...
];

export const routing = RouterModule.forRoot(routes);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...