Code Monkey home page Code Monkey logo

Comments (8)

adamkl avatar adamkl commented on July 28, 2024 3

Hey Yogu, I was just working on this exact scenario last week and came up with pretty much the same solution you suggested.
It was very easy to take a look at your code to see how it could be extended. You guys did a great job with the design and API!

from graphql-weaver.

Yogu avatar Yogu commented on July 28, 2024

Good question; we faced this use case, too.

You can pass a custom GraphQLClient instance for endpoints to completely customize how data is fetched. In your situation, I'd suggest to extend HttpGraphQLClient:

class AuthForwardingGraphQLClient extends HttpGraphQLClient {
    protected async getHeaders(document: DocumentNode, variables?: { [name: string]: any }, context?: any, introspect?: boolean): Promise<{ [index: string]: string }> {
        const headers = await super.getHeaders(document, context, introspect);
        return {
            ...headers,
            Authentication: getAuthTokenFromGraphQLContext(context)
        };
    }
}

const schema: GraphQLSchema = await weaveSchemas({
    endpoints: [{
        namespace: 'library',
        client: new AuthForwardingGraphQLClient('http://example.com/graphql')
    }]
});

Then, you somehow need to implement getAuthTokenFromGraphQLContext. How this is done depends on your GraphQL server implementation. If you use express-graphql, the express Request object is passed as context, by default. Then, something like this would do the job:

function getAuthTokenFromGraphQLContext(context: any) {
    if (!context) {
        return undefined;
    }
    return context.header('Authentication');
}

There is one pitfall: When you call weaveSchemas, the endpoints are already called with an introspection query. At this time, there is no context. If you need an authentication token for introspection queries, you need to provide it thorugh a different manner, e.g. by configuration. Use the introspect argument to getHeaders to distinguish those initial introspection queries from normal queries by users.

from graphql-weaver.

gengjiawen avatar gengjiawen commented on July 28, 2024

I followed your advice , but I still can't make it work, this is the demo code https://github.com/gengjiawen/schema-stitching-demo/tree/feature/pass_header, can you take a look when you have free time ? Thanks.

from graphql-weaver.

Yogu avatar Yogu commented on July 28, 2024

Sorry, I confused Authentication and Authorization. Also, express seems to convert the header names to lower case for some reason. I tested it locally and it at least dumped the correct token, though I did not test it with a real auth token. See this pull request in your project for the changes.

I only now realized you wrote Origin. Do you mean the HTTP Origin header? I assumed you meant authorization because you wrote token. If you want to forward the origin, just replace the header name.

from graphql-weaver.

gengjiawen avatar gengjiawen commented on July 28, 2024

thanks, I will give it a try tomorrow.

from graphql-weaver.

gengjiawen avatar gengjiawen commented on July 28, 2024

It works like as expected now, thanks. But why when i first running, I got log looks like this in the sample https://github.com/gengjiawen/schema-stitching-demo/tree/feature/pass_header? looks like the context not passed when get schema.

pass undefined
pass undefined
not valid undefined
not valid undefined

from graphql-weaver.

gengjiawen avatar gengjiawen commented on July 28, 2024

I see, that's because that time express-graphql is not used. Thanks for your great patience and help.

from graphql-weaver.

gengjiawen avatar gengjiawen commented on July 28, 2024

For anyone want to pass all the original headers, you can do something like this:
Notice to remove content-length from original header, or you will get timeout exception. This is found by @FX-HAO

class AuthForwardingGraphQLClient extends HttpGraphQLClient {
  protected async getHeaders(document: DocumentNode, variables?: { [name: string]: any }, context?: any, introspect?: boolean): Promise<{ [index: string]: string }> {
    const headers = await super.getHeaders(document, context, introspect);
    console.log('headers', headers)
    if (context) {
      console.log('context headers', context.headers)
      delete context.headers['content-length']
      return context.headers
    } else {
      return headers
    }
  }
}

from graphql-weaver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.