我正在用角度8中的Firebase来验证前端和后端的用户。要在后端对用户进行身份验证,我需要发送用户ID令牌。
我正在使用firebase getIdToken来获取令牌,并且它只能部分工作。刷新页面时,发生错误“ TypeError:无法读取null的属性'getIdToken'”。
我试图将令牌硬编码为getToken()方法,即使刷新也可以使用,但这是不可行的,所以我使getToken方法返回Observable。
在Http拦截器TokenInterceptorService中获取该可观察对象,以将该令牌添加到所有请求中。
export class AuthService {
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
public ngZone: NgZone // NgZone service to remove outside scope warning
) {}
// Other authentication methods for sign up etc.
// removed here for readability
getToken(): Observable<string> {
// getIdToken() returns promise so using 'from' to
// convert it to an Observable
const result = from(this.afAuth.auth.currentUser.getIdToken()
.then( token => {
console.log(token);
return token;
})
);
return result;
}
}
export class TokenInterceptorService implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.authService.getToken()
.pipe(
switchMap(token => {
const newRequest = request.clone({
setHeaders: {Authorization: `JWT ${token}`}
});
return next.handle(newRequest);
})
);
}
}
我看到过类似的my wrong example,并且正在使用该解决方案进行一些修改。
我什至尝试从getToken()方法返回promise,但这也不起作用。
答案 0 :(得分:2)
获取currentUser
是异步的,因此可以预期最初它是null
。就像documentation中提到的那样:
注意:
currentUser
也可能为空,因为auth
对象尚未完成初始化。
相反,您应该使用authState
来获取当前用户。然后,从您那里获得的用户,可以调用getIdToken()
,这将返回一个承诺。您可以在此处使用from
将其转换为可观察的:
getToken(): Observable<string | null> {
return this.afAuth.authState.pipe(
take(1),
switchMap((user) => {
if (user) {
return from(user.getIdToken())
}
return of(null);
})
)
}
然后在您的拦截器中,也检查令牌是否存在。如果没有用户,它将返回null