使用angularfire2和firebase的Angular 5身份验证应用程序。该应用程序可以使用应用程序内链接正常浏览。但是,如果我点击浏览器刷新,它将重定向我回到“登录”页面。因为我使用firebase成功登录后,即使true时,allowed总是返回False。
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']);
}
}),
);
}
}
答案 0 :(得分:2)
authInfo$
用UNKNOWN_USER
初始化,这将始终使第一个触发值不为真,重新加载时,您仅采用第一个值take(1)
,这是默认值。
一种解决方案是使第一个值null
并在防护中使用的Observable中过滤null
值:
AuthService
...
new BehaviorSubject<AuthInfo>(null);
...
AuthGuard
...
return this.authService.authInfo$.pipe(
filter(_ => _ !== null),
map(authInfo => authInfo.isLoggedIn()),
take(1),
...
这样,只有具有警卫意义的值才会被触发。