我的 authGuard 总是返回 false,因为 Firebase 需要几毫秒的时间才能将
currentUserSig()
更改为 true。有人可以帮忙吗?
// auth.guard.ts
import { inject } from "@angular/core"
import { AuthService } from "./auth.service"
import { Router } from "@angular/router";
export const authGuard = () => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.currentUserSig()) {
return true
} else {
router.navigate(['/login'])
return false;
}
}
// app.routes.ts
import { Routes } from '@angular/router';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { authGuard } from './auth/auth.guard';
export const routes: Routes = [
{path: '', component: DashboardComponent, canActivate: [authGuard]},
{path: 'login', component: LoginComponent,},
{path: 'register', component: RegisterComponent,},
];
这就是处理用户身份验证的
// auth.service.ts
import { Injectable, inject, signal } from "@angular/core";
import { Observable, from } from "rxjs";
import { Auth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
updateProfile,
user
} from "@angular/fire/auth";
import { UserInterface } from "./user.interface";
@Injectable({
providedIn: 'root'
})
export class AuthService {
firebaseAuth = inject(Auth)
user$ = user(this.firebaseAuth);
currentUserSig = signal<UserInterface | null | undefined>(undefined)
register(
email: string,
username: string,
password: string
) : Observable<void> {
const promise = createUserWithEmailAndPassword(
this.firebaseAuth,
email,
password
).then(response => updateProfile(response.user, {displayName: username}))
return from(promise);
}
login(
email: string,
password: string
) : Observable<void> {
const promise = signInWithEmailAndPassword(
this.firebaseAuth,
email,
password
).then(() => {});
return from(promise);
}
logout(): Observable<void>{
const promise = signOut(this.firebaseAuth);
return from(promise);
}
}
我不知道如何解决这个问题,因为大多数解决方案都处理已弃用的方法(即 canActivate),并且我无法从文档中找出答案。
我还没有真正弄清楚信号,但在我看来,它不会像你的那样工作。 但是,Firebase 有一个单独的方法,仅用于检查用户是否登录。 在我的项目中,我在服务中实现了这个方法,并且直接在守卫中实现了这个服务。 这是工作版本,请看一下,它可能对您有用。
import { inject, Injectable } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { map, Observable, tap } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class PermissionsService {
constructor(private afAuth: AngularFireAuth) {}
canActivate(): Observable<boolean> {
return this.checkIsUserLogin();
}
private checkIsUserLogin(): Observable<boolean> {
return this.afAuth.authState.pipe(
map(user => !!user)
);
}
}
export const authGuard: CanActivateFn = (): Observable<boolean> => {
const permissionsService= inject(PermissionsService);
const router = inject(Router);
return permissionsService.canActivate().pipe(
tap((permission: boolean) => {
if (!permission) {
router.navigate(['/login']);
}
})
);
};