Angular 2 AuthGuard with Firebase Auth 每次都重定向到登录页面
Angular 2 AuthGuard with Firebase Auth redirects each time to SignIn page
我正在尝试使用 firebase-auth 为 Angular 2 应用程序构建 AuthGuard,但存在一个问题。
应用程序加载后如果我因为异步操作而在 AuthGuard
returns false
中签名。
最终效果是当页面首先加载 AuthGuard
returns 时 false
然后 true
,所以每次都重定向到登录页面而不是根页面。
我认为我使用 *ngIf 仅显示 SignInComponent
,如果用户未登录,但这不是解决方案,因为每次 SignInComponent 都会在短时间内可见。
如何解决这个问题不立即重定向到登录页面?
谢谢您的回答。
AuthService
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
user: Observable<firebase.User>;
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private afAuth: AngularFireAuth) {
this.afAuth.authState.subscribe(
auth => {
if (auth) {
const authInfo = new AuthInfo(auth.uid);
this.authInfo$.next(authInfo);
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
}
},
err => {
console.log(err);
}
);
}
}
AuthInfo
export class AuthInfo {
constructor(
public $uid: string
) {
}
isLoggedIn() {
return !!this.$uid;
}
}
AuthGuard
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.authInfo$
.map( authInfo => authInfo.isLoggedIn())
.take(1)
.do(allowed => {
console.log('authguard: ' + allowed);
if (!allowed) {
this.router.navigate(['/signin']);
}
});
}
}
抱歉,这是
的重复问题
我的解决方案是
AuthService
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private afAuth: AngularFireAuth) {}
getAuthInfo(): Observable<AuthInfo> {
return this.afAuth.authState.map(
auth => {
if (auth) {
const authInfo = new AuthInfo(auth.uid);
this.authInfo$.next(authInfo);
return authInfo;
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
return AuthService.UNKNOWN_USER;
}
},
err => {
console.log(err);
}
);
}
AuthGuard
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
if (this.authService.authInfo$.getValue().isLoggedIn()) {
return true;
}
return this.authService.getAuthInfo()
.map( (authInfo: AuthInfo) => authInfo.isLoggedIn())
.do(allowed => {
if (!allowed) {
this.router.navigate(['/signin']);
return false;
} else {
return true;
}
}).take(1);
}
}
我正在尝试使用 firebase-auth 为 Angular 2 应用程序构建 AuthGuard,但存在一个问题。
应用程序加载后如果我因为异步操作而在 AuthGuard
returns false
中签名。
最终效果是当页面首先加载 AuthGuard
returns 时 false
然后 true
,所以每次都重定向到登录页面而不是根页面。
我认为我使用 *ngIf 仅显示 SignInComponent
,如果用户未登录,但这不是解决方案,因为每次 SignInComponent 都会在短时间内可见。
如何解决这个问题不立即重定向到登录页面?
谢谢您的回答。
AuthService
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
user: Observable<firebase.User>;
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private afAuth: AngularFireAuth) {
this.afAuth.authState.subscribe(
auth => {
if (auth) {
const authInfo = new AuthInfo(auth.uid);
this.authInfo$.next(authInfo);
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
}
},
err => {
console.log(err);
}
);
}
}
AuthInfo
export class AuthInfo {
constructor(
public $uid: string
) {
}
isLoggedIn() {
return !!this.$uid;
}
}
AuthGuard
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.authInfo$
.map( authInfo => authInfo.isLoggedIn())
.take(1)
.do(allowed => {
console.log('authguard: ' + allowed);
if (!allowed) {
this.router.navigate(['/signin']);
}
});
}
}
抱歉,这是
我的解决方案是
AuthService
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private afAuth: AngularFireAuth) {}
getAuthInfo(): Observable<AuthInfo> {
return this.afAuth.authState.map(
auth => {
if (auth) {
const authInfo = new AuthInfo(auth.uid);
this.authInfo$.next(authInfo);
return authInfo;
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
return AuthService.UNKNOWN_USER;
}
},
err => {
console.log(err);
}
);
}
AuthGuard
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
if (this.authService.authInfo$.getValue().isLoggedIn()) {
return true;
}
return this.authService.getAuthInfo()
.map( (authInfo: AuthInfo) => authInfo.isLoggedIn())
.do(allowed => {
if (!allowed) {
this.router.navigate(['/signin']);
return false;
} else {
return true;
}
}).take(1);
}
}