【发布时间】:2018-04-10 06:19:37
【问题描述】:
我正在尝试使用 Angularfire2 和 Angular4 为学校作业构建基于角色的授权。但是,它正在工作,当我刷新页面时,我被重定向到登录页面,因为在 Angularfire 从 Firebase DB 获取用户(+角色)之前执行了 Guard。 我想让最终用户重新加载页面而不被重定向到登录页面。
我搜索了很多网站,但找不到任何有用的东西。许多网站解释了如何支持重新加载但不使用用户角色(因此没有 Firebase DB 查询),而其他网站解释了如何使用多个用户角色但不支持页面重新加载。
我的(相关)代码:
auth.service.ts:
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { User } from '../models/user.model';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/take';
@Injectable()
export class AuthService {
user: BehaviorSubject<User> = new BehaviorSubject(null);
constructor (private afAuth: AngularFireAuth, private db: AngularFireDatabase) {
this.afAuth.authState
.switchMap(auth => {
console.log(auth);
if (auth) {
/// signed in
return this.db.object('users/' + auth.uid);
} else {
/// not signed in
return Observable.of(null);
}
})
.subscribe(user => {
this.user.next(user);
});
}
googleLogin () {
const provider = new firebase.auth.GoogleAuthProvider();
return this.afAuth.auth.signInWithPopup(provider)
.then(credential => {
return this.updateUser(credential.user);
});
}
signOut () {
return this.afAuth.auth.signOut();
}
private updateUser (authData) {
const userData = new User(authData);
const ref = this.db.object('users/' + authData.uid);
return ref.take(1).subscribe(user => {
if (!user.name) {
ref.update(userData);
}
});
}
}
guard.ts:
import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {AuthService} from '../shared/services/auth.service';
import * as _ from 'lodash';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
@Injectable()
export class AdminGuard implements CanActivate {
constructor (private auth: AuthService, private router: Router) {}
canActivate (next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
return this.auth.user
.take(1)
.map(user => _.get(_.get(user, 'roles'), 'admin'))
.do(authorized => {
if (!authorized) {
this.router.navigate(['/login']);
}
});
}
}
提前致谢!
【问题讨论】:
标签: angular typescript firebase asynchronous angularfire2