Ado*_*Ren 9 javascript firebase firebase-authentication angularfire2 angular
我想在“真正”启动单页应用程序之前,在 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 ?
})
}
Run Code Online (Sandbox Code Playgroud)
有可能实现这样的行为吗?我读过有关 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();
}
})
});
}
}
Run Code Online (Sandbox Code Playgroud)
并编辑了 AppModule 提供程序:
providers: [
interceptorProviders /* my interceptors */,
{
provide: APP_INITIALIZER,
useFactory: initApp,
deps: [AuthService, AngularFireAuth],
multi: true
}
]
Run Code Online (Sandbox Code Playgroud)
仍然需要弄清楚如何添加等待徽标,但这是另一个问题。我会尽快更新。
回答我自己的问题
总而言之,在处理路由之前,我想确保与 Firebase 用户关联的令牌声明(角色和用户 ID)存储在我的身份验证服务中,因为这些路由内的组件将使用这些凭据。
最后我没有遵循 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;
}
Run Code Online (Sandbox Code Playgroud)
在 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>
Run Code Online (Sandbox Code Playgroud)
在组件中:
credentials$: Observable<any>;
constructor(
private auth: AuthService,
) {
this.credentials$ = this.auth.credentials$;
}
Run Code Online (Sandbox Code Playgroud)
授权卫士
在进一步操作之前,花时间可以让我确保我的凭据已设置。
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)
}
})
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2634 次 |
| 最近记录: |