在异步 setContext 中等待身份验证
authentication await in async setContext
在文档 ( https://www.apollographql.com/docs/angular/recipes/authentication/ ) 中有一个示例。
然而,这不起作用,如果你有一个 angular-apollo watch().valueChanges 或 fetch() 作为返回的 Observable...
我的代码是:
const auth = setContext(async (_, {headers}) => {
let token = authService.getAccessToken();
if (!authService.hasValidAccessToken()) {
if (authService.hasRefreshToken()) {
await this.authService.refreshToken().pipe(first()).toPromise(); //Does not work...
token = authService.getAccessToken();
}
}
// Return the headers as usual
return {
headers: {
Authorization: `Bearer ${token}`,
},
};
});
authService.refreshToken() 方法返回这个:
refreshToken(): Observable<any> {
this.removeAccessToken();
if (this.hasRefreshToken()) {
return this.refreshGQL.fetch({
refreshToken: this.getRefreshToken()
}).pipe(
tap(next => {
this.storeTokens(next.data.refresh);
}
)
);
}
问题是,无法调用订阅,这将启动 Observable。
你有解决办法吗?
ok,这跟 await for promise 和 observable to promise 无关。
完全正确。
这只是一个典型的僵局。
如果没有有效的访问令牌,它将尝试接收一个新的,从而产生一个 gql 请求,它也没有有效的访问令牌,它将尝试为每个 gql 请求接收一个新的,等等...
如果操作名称等于刷新突变或查询,只需跳过逻辑即可解决。
在文档 ( https://www.apollographql.com/docs/angular/recipes/authentication/ ) 中有一个示例。 然而,这不起作用,如果你有一个 angular-apollo watch().valueChanges 或 fetch() 作为返回的 Observable...
我的代码是:
const auth = setContext(async (_, {headers}) => {
let token = authService.getAccessToken();
if (!authService.hasValidAccessToken()) {
if (authService.hasRefreshToken()) {
await this.authService.refreshToken().pipe(first()).toPromise(); //Does not work...
token = authService.getAccessToken();
}
}
// Return the headers as usual
return {
headers: {
Authorization: `Bearer ${token}`,
},
};
});
authService.refreshToken() 方法返回这个:
refreshToken(): Observable<any> {
this.removeAccessToken();
if (this.hasRefreshToken()) {
return this.refreshGQL.fetch({
refreshToken: this.getRefreshToken()
}).pipe(
tap(next => {
this.storeTokens(next.data.refresh);
}
)
);
}
问题是,无法调用订阅,这将启动 Observable。 你有解决办法吗?
ok,这跟 await for promise 和 observable to promise 无关。 完全正确。
这只是一个典型的僵局。
如果没有有效的访问令牌,它将尝试接收一个新的,从而产生一个 gql 请求,它也没有有效的访问令牌,它将尝试为每个 gql 请求接收一个新的,等等...
如果操作名称等于刷新突变或查询,只需跳过逻辑即可解决。