在Firebase身份验证正在检索用户令牌时,我想显示一个小的加载徽标,然后再启动“真正”的单页应用程序。
到目前为止,我有身份验证服务:
constructor(
public afAuth: AngularFireAuth,
) {
this.afAuth.onAuthStateChanged(user => {
if (user) {
this.setCredentials(user)
}
})
}
setCredentials(user: firebase.User) {
return user.getIdTokenResult(true).then(idTokenResult => {
this.credentials = {
userId: idTokenResult.claims.id,
role: idTokenResult.claims.role,
token: idTokenResult.token,
};
// STARTS THE APPLICATION NOW ?
})
}
是否有可能实现这种行为?我读过关于APP_INITIALIZER的信息,但没有成功。我想避免使用本地存储/会话存储,而只依赖于此初始化。
更新:
创建了一个初始化函数:
export function initApp(auth: AuthService, afAuth: AngularFireAuth) {
return () => {
return new Promise((resolve) => {
afAuth.user.pipe(
take(1),
).subscribe(user => {
if (user) {
auth.setCredentials(user)
.then(() => resolve())
} else {
resolve();
}
})
});
}
}
以及修改后的AppModule提供程序:
providers: [
interceptorProviders /* my interceptors */,
{
provide: APP_INITIALIZER,
useFactory: initApp,
deps: [AuthService, AngularFireAuth],
multi: true
}
]
仍然需要弄清楚如何添加等待中的徽标,但这是另一个问题。我将尽快更新。
答案 0 :(得分:0)
您应该在CanActivate
路由器保护程序中使用身份验证服务:https://angular.io/api/router/CanActivate
这意味着您的AppModule将首先加载,然后您的子路由(例如,带有路由器路径''的MainModule)具有防护功能。然后在AppModule中,您可以检查服务的状态并显示加载信息,直到MainModule被激活(firebase身份验证完成时)
答案 1 :(得分:0)
回答我自己的问题
总而言之,我想确保与Firebase用户相关联的令牌声明(角色和每个发言的用户ID)在处理路由之前已存储在我的auth服务中,因为这些路由内的组件会使用这些凭据。
最后,我没有遵循APP_INITIALIZER,这并不是一个很好的解决方案。
身份验证服务
private _credentials: BehaviorSubject<Credentials> = new BehaviorSubject<Credentials>(null);
public readonly credentials$: Observable<Credentials> = this._credentials.asObservable();
constructor(private afAuth: AngularFireAuth) {
this.afAuth.authState.subscribe(user => {
this._credentials.next(null);
if (user) {
user.getIdTokenResult().then(data => {
const credentials = {
role: data.claims.role,
token: data.token,
userId: data.claims.userId
}
this._credentials.next(credentials);
console.log(credentials);
})
} else {
this._credentials.next({role: null, token: null, userId: null});
}
})
}
get credentials(): Credentials {
return this._credentials.value;
}
在app.component中显示正在等待的微调器
如果未设置凭据,则以下阻止显示路由。 在模板中:
<div *ngIf="!(credentials$ | async)" class="logged-wrapper">
<div class="spinner-wrapper">
<mat-spinner class="spinner"></mat-spinner>
</div>
</div>
<router-outlet *ngIf="(credentials$ | async)"></router-outlet>
在组件中:
credentials$: Observable<any>;
constructor(
private auth: AuthService,
) {
this.credentials$ = this.auth.credentials$;
}
Auth Guard
需要一段时间,我才能确保设置了凭据,然后再继续操作。
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot):Promise<boolean> {
return new Promise((resolve) => {
this.auth.credentials$.pipe(
takeWhile(credentials => credentials === null),
).subscribe({
complete: () => {
const credentials = this.auth.credentials
if (!credentials.role) {
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } })
resolve(false);
}
if (next.data.roles && next.data.roles.indexOf(credentials.role) === -1) {
this.router.navigate(['/']);
resolve(false);
}
resolve(true)
}
})
})
}