Replies: 1 comment
-
This is more a question for the apollo gateway.
import DataSource from './runtime/DataSource';
...
// Apollo gateway config
const gateway = new ApolloGateway({
serviceList: [
{ name: "...", url: "..." },
...
],
buildService({ url }) {
// datasource to handle authentication, tracing and trim subscriptions
return new DataSource({
config,
url,
logger: logger.child({ module: 'graphql datasource resolver' }),
});
},
}); The custom datasource component looks somewhat like shown below. I've omitted logging code and the handling of trace spans for the sake of brevity. I've also omitted the retrieval of some service account credentials to introspect remote schemas when the gateway starts up. export default class AuthenticatedDataSource extends RemoteGraphQLDataSource {
...
// willSendRequest is applied before any request sent upstream by the Apollo gateway.
willSendRequest({ request, context }): ValueOrPromise<void> {
...
if (
!request ||
!request.query ||
!request.http ||
typeof request.http.headers === 'undefined'
) {
...
return undefined;
}
// propagate headers to back-end, including tracing
const extraHeaders: Record<string, string> = {};
...
request.http.headers = copyHeaders(
context.req,
extraHeaders,
request.http.headers,
...
// propagates everything related to B3 tracing (interoperable with opencensus tracing)
'x-b3-spanid',
'x-b3-traceid',
'x-b3-sampled',
'x-b3-parentspanid',
'x-b3-flags',
// propagates authentication
'authorization',
// propagates content negotiation headers
'accept',
'accept-encoding',
'accept-charset',
'accept-language',
'range',
);
// __ApolloGetServiceDefinition__ and __ApolloServiceHealthCheck__
// are internal queries from the gateway to poll remote services for introspection
if (!request.query.match(/query\s+__(ApolloGetServiceDefinition|ApolloServiceHealthCheck)__/)) {
...
// authorization header is assumed to be brought in by the caller
return undefined;
}
// background introspection query: use service account authentication
if (request.http.headers && request.http.headers.has('Authorization')) {
// all headers already in here, do nothing
...
return undefined;
}
...
return this.serviceAccount.getToken() // a promise to authenticate as service account and get a token
.then<void>((token: string): void => {
if (token === '') {
// something went wrong
throw new Error('cannot acquire auth token');
}
if (!request || !request.http) {
return;
}
this.logger.debug('willSendRequest adding service account credentials');
request.http.headers.set('Authorization', `Bearer ${token}`);
})
}
function copyHeaders(
req: IncomingMessage,
extra: Record<string, string>,
to: Headers,
...headers: string[]
): Headers {
// copy select headers from request
...
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
What happened?
I'm building a graphql api with gqlgen and apollo federation as a gateway.
in gqlgen, I have three services: static page, accounts, auth.
And I'm using apollo federation as a gateway.
For the auth section I need to get Authorization header like
r.Header.Get("Authorization")
in middleware. But it is empty.How can I pass headers from apollo federation gateway to gqlgen server?
What did you expect?
All headers from gateway pass to implemented services (gqlgen).
Minimal graphql.schema and models to reproduce
versions
gqlgen: v0.13.0
go1.15.1
gomod
Beta Was this translation helpful? Give feedback.
All reactions