angular - 如果使用搜索栏导航到 URI,则 Angular 身份验证防护失败
问题描述
我已经在我的应用程序中设置了一个可注入来处理身份验证:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import {AngularFireAuth} from '@angular/fire/auth';
import {SnackService} from '../../services/snack.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private afAuth: AngularFireAuth,
private snack: SnackService
) {}
async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
const user = await this.afAuth.auth.currentUser;
const isLoggedIn = !!user;
if (!isLoggedIn) {
this.snack.authError();
}
return isLoggedIn;
}
}
如果我登录到我的应用程序并通过单击链接重定向到路由,即/projects/1
,一旦警卫检查完成,我就会成功定向,但是如果我手动将浏览器定向到相同的 URI,我会被踢回主页并告诉我未授权(通过我的零食服务,它将我重定向到登录页面并闪烁祝酒词说我需要登录)
如果我修改我的代码以引入一些人为的减速:
async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
await this.timeout(300);
const user = await this.afAuth.auth.currentUser;
const isLoggedIn = !!user;
console.log(this.afAuth.auth.currentUser);
if (!isLoggedIn) {
this.snack.authError();
}
return isLoggedIn;
}
timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
然后我可以通过链接直接到路由或通过地址栏手动点击 URI,让我相信应用程序已经被引导和加载,但是在身份验证提供程序完成初始化之前检查身份验证保护,导致第一次进行空检查。
显然,我不想在每个页面上留下 300 毫秒的延迟,只是为了确保在没有经过身份验证的情况下无法导航到受保护的页面。在我检查currentUser
属性之前,有什么方法可以订阅正在初始化的身份验证提供程序?
解决方案
我之前遇到过同样的问题,我的解决方法是返回一个 Observable 而不是 Promise 并像这样使用 rxjs 管道:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable < boolean > {
return from(this.afAuth.auth.currentUser).pipe(
switchMap(user => {
const isLoggedIn = !!user;
if (!isLoggedIn) {
this.snack.authError();
}
return isLoggedIn;
})
);
}
让我知道它是否有效
推荐阅读
- flutter - Flutter 重复文件包和依赖
- gcc - 使用 gstreamer 构建静态二进制文件时遇到问题
- python - 使用来自模型外部的数据填充 Django 表单下拉列表
- python - StandardScaler:TypeError:fit()缺少1个必需的位置参数:'X'
- node.js - TypeError:配置文件不是构造函数
- asp.net - 如何在主从 CRUD 上查看特定 id 的记录?
- android - Git 和 Android Studio 的奇怪行为
- azure-devops - Azure Devops - 为每个部署环境创建一个映射变量
- docker - 如何在 OpenJ9/Alpine 容器上使用 JProfiler 12.0.3 设置远程分析
- java - Java随机名称生成器,选择单词的长度