Angular canActivate перенаправление для входа в систему при обновлении браузера Firebase - PullRequest
0 голосов
/ 05 июля 2018

Angular 5 приложение для аутентификации с использованием angularfire2 и firebase. Приложение отлично работает, используя ссылки в приложении. Однако, если я нажму кнопку обновления браузера, он перенаправит меня обратно на страницу входа. Разрешенный всегда возвращает False, даже если это правда, потому что я сделал успешный вход в систему с помощью firebase.

AuthInfo

export class AuthInfo {  
    constructor(public $uid: string) {}

    isLoggedIn() {
        // console.log(this.$uid);
        return !!this.$uid;
    }
}

AuthService

import { Injectable } from '@angular/core';
// tslint:disable-next-line:import-blacklist
import {Observable, Subject, BehaviorSubject} from 'rxjs/Rx';
import {AngularFireAuth } from 'angularfire2/auth';
import { AuthInfo } from '../security/auth-info' ;
import {Router} from '@angular/router';
import * as firebase from 'firebase/app';

@Injectable()
export class AuthService {
  static UNKNOWN_USER = new AuthInfo(null);
  authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);

  constructor(private afAuth: AngularFireAuth, private router: Router) {}
    login(email, password): Observable<AuthInfo> {
        return this.fromFirebaseAuthPromise(this.afAuth.auth.signInWithEmailAndPassword(email, password));
    }

    // signUp(email, password) {
    //  return this.fromFirebaseAuthPromise(this.afAuth.auth.createUserWithEmailAndPassword(email, password));
    // }

    fromFirebaseAuthPromise(promise): Observable<any> {
        const subject = new Subject<any>();
        promise
              .then(res => {
                    const authInfo = new AuthInfo(this.afAuth.auth.currentUser.uid);
                    this.authInfo$.next(authInfo);
                    subject.next(res);
                    subject.complete();
                    // console.log(res);
                },
                err => {
                    this.authInfo$.error(err);
                    subject.error(err);
                    subject.complete();
                });
        return subject.asObservable();
    }

    logout() {
        this.afAuth.auth.signOut();
        this.authInfo$.next(AuthService.UNKNOWN_USER);
        this.router.navigate(['/login']);
    }
    refresh() {
        const url = window.location.href;
    } 
}

AuthGuard

import {tap, take, map} from 'rxjs/operators';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router';
// tslint:disable-next-line:import-blacklist
import {Observable} from 'rxjs/Rx';
import {Injectable} from '@angular/core';
import {AuthService} from '../security/auth-service';
import { Location } from '@angular/common';
import { auth } from 'firebase';
import { log } from '@firebase/database/dist/src/core/util/util';

@Injectable()
export class AuthGuard implements CanActivate {
    redirectUrl: string;
    currentURL= '';
    constructor(private authService: AuthService, private router: Router) {}

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

        // tslint:disable-next-line:no-unused-expression
        console.log(this.authService.authInfo$);

        return this.authService.authInfo$.pipe(
            map(authInfo => authInfo.isLoggedIn()),
            take(1),
            tap(allowed => {
                if  (!allowed) {
                    console.log(allowed);
                     this.router.navigate(['/login']);
                }
            }),
        );
    }
}

1 Ответ

0 голосов
/ 05 июля 2018

authInfo$ инициализируется с UNKNOWN_USER, что всегда делает первое запущенное значение неверным, при перезагрузке вы берете только первое значение take(1), которое является значением по умолчанию.

Одно из решений заключается в создании первого значения null и фильтрации null значений в Observable, используемых в охране:

AuthService

...
new BehaviorSubject<AuthInfo>(null);
...

AuthGuard

...
return this.authService.authInfo$.pipe(
  filter(_ => _ !== null),
  map(authInfo => authInfo.isLoggedIn()),
  take(1),
...

Таким образом, будут запускаться только те значения, которые имеют значение для охранника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...