Angular Firestore Admin Auth Guard



我正在尝试阻止普通用户访问我的应用程序的管理端。 目前,Firestore 文档上的 admin 属性为 true 或 false。如果为 false,则应在尝试访问主页时将其重定向到主页,否则允许用户继续访问该页面。

这是我的admin-auth-guard.service.ts

userDoc: AngularFirestoreDocument<User>;
user: Observable<User>;
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router) {}
canActivate() {
this.userDoc = this.afs.doc('users/' + this.afAuth.auth.currentUser.uid);
this.user = this.userDoc.valueChanges();
return this.user.map(role => {
if (role.admin)
return true
this.router.navigate(['/']);
return false;        
});
}

我相信代码会起作用,尽管在初始化管理员身份验证保护时,请求发生得太快并且 uid 为空。

我收到此错误:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'uid' of null
TypeError: Cannot read property 'uid' of null

Firestore和Angle似乎是一个利基话题,关于两者的信息并不多。任何帮助将不胜感激!

当您同步访问uid时,您不能依赖对其进行初始化,因为当用户(内部(进行身份验证时,Firebase 会填充它。我宁愿将其视为可观察对象并异步访问它。

因此,让我们将其设置为可观察的,创建一个auth.service.ts文件:

Injectable()
export class FirebaseAuthService {
constructor(
private angularFireAuth: AngularFireAuth,
private angularFirestore: AngularFirestore,
) {
}
getUser(): Observable<any> {
return this.angularFireAuth.authState.pipe(
mergeMap(authState => {
if (authState) {
return from(this.angularFirestore.doc(`users/${authState.uid}`).get());
} else {
return NEVER;
}
})
);
}
// is logged in?
// signin
// more auth related methods
}

所以人们可以订阅getUser().每当全局身份验证状态更改时,authState都会发出一个项目。定义此项(因此对用户进行身份验证(时,将向 firestore 发出请求,以检索用户文档。如果未定义authState(因此用户未进行身份验证(,将发出NEVER,这意味着不会返回任何内容,并且不会终止可观察量。

现在在身份验证保护中使用此类:

@Injectable()
export class AdminAuthGuardService implements CanActivate {
constructor(
private router: Router,
private firebaseAuthService: FirebaseAuthService,
) {
}
canActivate() {
return this.firebaseAuthService.getUser().pipe(
map(user => {
if (!user || !user.admin) {
// noinspection JSIgnoredPromiseFromCall
this.router.navigate(['/login']);
return false;
}
return true;
}),
take(1),
);
}
}

我们将复杂性保留在身份验证服务中,因此身份验证保护变得非常愚蠢。它订阅getUser,并在用户未定义(未经过身份验证(或不是管理员时重定向到登录。

最新更新