我是Web技术的初学者,并试图编写一个使用Firebase进行身份验证的Angular应用(用于移动设备和Web)。
我的应用程序组件HTML就是这样。
<NavBar Component>
<SideBar Component> //visibility toggled based on action from the navbar
<Router Outlet>
我使用了一些路由,例如/ home,/ checkout,/ user / login和/ user / profile。
基于登录状态,导航栏中的项目将显示为“登录”或“用户个人资料”,以使用户导航到/ user / login或/ user / profile
firebase上的Authentication Service可以正常工作,我能够获取登录的用户信息并更改navbar项中的路由器链接。
当我刷新窗口时出现问题。刷新窗口时,firebase Auth用户为空,它需要几秒钟来设置和发送用户数据。因此,导航栏项会显示“登录”几秒钟,然后更改为“用户个人资料”
由于NavBar不在路由器出口内,所以我无法使用Resolver服务来解决此目的。
我应该使用本地存储来解决此问题吗?还是还有其他更好的解决方案?
答案 0 :(得分:0)
有很多方法可以对ngCat进行外观设置,但这对于Router Guard来说是一个很好的用例。路由器防护非常适合身份验证,并且是处理导航安全问题的更好场所。我强烈建议您重构代码,以确保所有需要身份验证的组件成为可以保护的路由的一部分。
路由器防护的本质是CanActivate方法,您可以在其中定义有关谁可以(或不能)继续加载受保护页面的条件。这是一个简单的赞许/拒绝布尔返回值,但较不常见的形式可以返回一个Observable,您可以在等待Firebase的初始身份验证调用返回时,使用它来阻止执行。
import { AngularFireAuth } from 'angularfire2/auth';
...
@Injectable({
providedIn: 'root',
})
...
export class AuthGuardService implements CanActivate {
...
constructor(private afAuth: AngularFireAuth, public router: Router) {}
...
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
const authenticated: Subject<boolean> = new Subject();
this.afAuth.auth.onAuthStateChanged(firebaseUser => {
if (!firebaseUser) {
this.router.navigate(['/user/login']);
authenticated.next(false);
} else {
authenticated.next(true);
}
authenticated.complete();
});
return authenticated;
}
在根路由表中引用防护:
const routes: Routes = [
{
path: '',
component: LayoutComponent,
children: [{ path: 'user', loadChildren: './user/user.module#UserModule' }],
canActivate: [AuthGuardService],
...
回顾一下,刷新页面(例如,重新加载应用程序)时,canActivate将触发,并且直到Firebase中存在authStateChange(链接到可观察对象)后,页面才会加载。因此,尽管加载所需的时间相同,但您看不到中间的过渡。
请注意,该调用由AngularFireAuth模块包装,但是在Firebase常规文档中引用了onAuthStateChanged模式作为跟踪身份验证更改的首选方法。
祝你好运!
参考文献: