Issue
During my angular application startup process, I need to asynchronously get a config file which contains my graphql URI (uri is generated during CI/CD pipeline). To achieve this I can use the APP_INITIALIZER token to do some async loading. This works well enough to setup a default apollo client.
export function createApollo(apolloOptionsService: ApolloOptionsService) {
return async (): Promise<any> => {
return await lastValueFrom(apolloOptionsService.createApollo$()
.pipe(filter(val => !!val))
.pipe(take(1)));
};
}
export function getApolloOptions(apolloOptionsService: ApolloOptionsService) {
return apolloOptionsService.getApolloOtionsValue();
}
@NgModule({
imports: [ApolloModule, HttpClientModule],
providers: [
ApolloOptionsService,
{
provide: APP_INITIALIZER,
useFactory: createApollo,
deps: [ApolloOptionsService],
multi: true
},
{
provide: APOLLO_OPTIONS,
useFactory: getApolloOptions,
deps: [ApolloOptionsService]
},
Apollo
]
})
export class GraphQLModule {}
Problem: To get an access token, I need to make a call using the Auth0 library. I cannot use the Auth0 library during the createApollo
factory method because the auth0 service hasn't been instantiated yet because of the APP_INITIALIZER
startup sequence.
As a work around, I've decided to take the approach of appending the headers at the request level.
return forkJoin([this.userRole$, this.getAccessToken$()])
.pipe(
switchMap(res => {
const roles = res[0];
const accessToken = res[1] as string;
return this.apollo
.watchQuery({
query: gql`
${ApiQueries.getStuff}
`,
variables: {
selected_user_role_id: roles?.rid,
tenant_id: roles?.tenantId
},
context: {
headers: {
Authorization: `Bearer ${accessToken}`
},
}
})
.valueChanges.pipe(
map((result: any) => {
return ApiParser.parseStuffResult(result);
}),
catchError((error) => this.errorHandler('getStuff$', error)),
);
})
);
Question:
Appending authorization headers on the request level doesn't work and when inspecting the network tab, i can see my headers aren't there, why?
Is there another way to get access to a jwt during startup?
Side note: I've verified that the headers are present and my requests work if I temporarily hard code a jwt in my apollo client setup
Solution
You want to append headers you should do so in an Apollo-Client link
Here's a simple authLink
:
const authLink = setContext(async (_, { headers }) => {
const token = await getToken(); // or however you get your token
if (token) headers['Authorization'] = `Bearer ${token}`;
return { headers };
});
Answered By - Michel Floyd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.