我有一个简单的 Ionic 4/5 选项卡式应用程序(我从他们的选项卡启动器开始)。我想制作一个由身份验证保护的选项卡。这是我想要实现的目标:
- 为登录用户、配置文件管理、帐户管理等保留选项卡之一。
- 因此,当用户单击第三个选项卡时,默认页面是由 AuthGuard 保护的“配置文件”,如果 ionic 存储中没有用户,则重定向到登录/注册页面
这是我到目前为止所尝试的:
@Injectable({
providedIn: 'root'
})
export class AuthService {
static STORAGE_KEY = 'auth-user';
user: BehaviorSubject<User> = new BehaviorSubject(null);
redirectUrl: string;
constructor(
@Inject(ROUTES_CONFIG)
private readonly ROUTES: AppRoutes,
private readonly router: Router,
private readonly storage: Storage,
private readonly platform: Platform,
private readonly http: HttpClient
) {
this.platform.ready().then(() => {
this.checkUser();
});
}
async checkUser() {
const user = await this.storage.get(AuthService.STORAGE_KEY) as User;
if (user) {
this.user.next(user);
}
}
login(credentials): Observable<any> {
const loginObservable = this.http.post(`http://localhost:3000/auth/login`, credentials);
loginObservable.subscribe(async (user: User) => {
await this.storage.set(AuthService.STORAGE_KEY, user);
this.user.next(user);
this.router.navigateByUrl(this.redirectUrl || this.ROUTES.AUTH);
});
return loginObservable;
}
async logout(): Promise<void> {
await this.storage.remove(AuthService.STORAGE_KEY);
this.user.next(null);
this.router.navigateByUrl(this.ROUTES.LOGIN);
}
isLoggedIn(): Observable<User> {
return this.user;
}
}
还有守卫:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | Observable<boolean> | boolean {
let url: string = state.url;
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
return this.authService
.isLoggedIn()
.pipe(
skip(1),
map(user => {
if (user) {
console.log('authenticated');
return true;
}
console.error('Not authenticated, redirecting to login');
this.router.navigateByUrl(this.ROUTES.LOGIN);
return false;
})
)
}
问题在于,一旦经过身份验证,authguard 就永远不会进入map
. 我把它放在skip(1)
那里是因为我想跳过初始null
值。我怎样才能“推迟”AuthGuard,直到我的 AuthService 检查用户是否存在于存储中,因为毕竟这就是我想要做的。