Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth login .then delay #560

Closed
ryanlangton opened this issue Sep 25, 2016 · 4 comments
Closed

Auth login .then delay #560

ryanlangton opened this issue Sep 25, 2016 · 4 comments

Comments

@ryanlangton
Copy link

ryanlangton commented Sep 25, 2016

Calling AngularFire.auth(...).then(...) the user may still not be authenticated yet in the .then portion. After the user logs in I'm attempting a redirect in the .then portion but my AuthGuard still fails. If I then manually change the route (by changing my browser URL) the AuthGuard passes.

Here is my login function on my login page/component.

  loginFacebook() {
    this.login(AuthProviders.Facebook);
  }

  loginGoogle() {
    this.login(AuthProviders.Google);
  }

  loginTwitter() {
    this.login(AuthProviders.Twitter);
  }

  login(provider: AuthProviders) {
    this.af.auth.login({
      provider: provider,
      method: AuthMethods.Popup,
    }).then((auth: FirebaseAuthState) => {
      console.log('authenticated!');
      this.auth.createUserIfNew(auth);
      this.auth.redirectAfterLogin();
    });
  }

My AuthService (called above with this.auth.redirectAfterLogin()):

    redirectAfterLogin() {
        if (this.storedPath && this.storedPath !== '') {
            console.log('go to stored path: ' + this.storedPath);
            this.router.navigate([this.storedPath]);
            this.storedPath = '';
        } else {
            console.log('go to profile');
            this.router.navigate(['/profile']);
        }
    }

    redirectToLogin(fromPath: string) {
        console.log('redirecting from ' + fromPath);
        this.storedPath = fromPath;
        this.router.navigate(['/login']);
    }

Here is my AuthGuard:

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private af: AngularFire, private router: Router, private auth: AuthService) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.af.auth.asObservable().take(1).map(auth => {
      if (auth && auth.auth) {
        console.log('auth passed');
        return true;
      }
      console.log('auth failed, store path: ' + state.url);
      this.auth.redirectToLogin(state.url);
      return false;
    });
  }
}

And my console.log output:

authenticated!
auth.service.ts:40 go to stored path: /profile
auth-guard.service.ts:27 auth failed, store path: /feed
auth.service.ts:33 redirecting from /feed
@christophertrudel
Copy link

I experience similar issues while logging out.

@andlcool
Copy link

Me too, experiencing the same problem

@tonymk
Copy link

tonymk commented Oct 17, 2016

A trick to get around it:

import { Observable } from 'rxjs/Rx';

Observable.of(null).delay(50).subscribe( () => {
  this.auth.redirectAfterLogin();
})

or my litle hack:

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(
        private router: Router,
        @Inject(FirebaseApp) private firebaseApp: any
    ) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        // return true if authenticated
        if (firebase.auth().currentUser) return Observable.of(true);

        // if no currentUser, give it 50ms more before declining, for firebase auth to check if you are logged in or not.
        return Observable.of(null).delay(50).map(() => {
            if (this.firebaseApp.auth().currentUser) { return true; }
            this.router.navigateByUrl('login');
            return false;
        });

    }

}

Edit: found a better way from https://blog.khophi.co/angularfire2-authentication/

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/first';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(
        private af: AngularFire,
        private router: Router
    ) { }

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

    }

}

@Energy4216
Copy link

I was about to update to latest af2 is this still an issue and does tonymk's trick work ok?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants