Skip to content

Include Authorization header in RootObject handler param #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

piinecone
Copy link

I'm using jwt in my application and I wanted to include the Authorization header in graphql requests so I can return the correct viewer and related data. I don't know, but I don't think this is the best way to accomplish this, and it's certainly not generic. I wanted to start a discussion.

@sogko Do you think it make sense to add this header to the RootObject and include it? I wasn't sure, and think it might be more appropriate to include it in the user context Context param.

It seems that in either case it would be easy to retrieve the header from the ResolveParams:

p.Info.RootValue.(map[string]interface{})["Authorization"].(string)

@sogko
Copy link
Member

sogko commented Mar 10, 2016

Hi @piinecone,

Thanks for contributing to this project and submitting a PR, we really appreciate it very much 👍🏻

GraphQL does not prescribe how to authenticate and authorise GraphQL requests, but it is understandably a main concern for any developer implementing a public facing GraphQL server.

I would not recommend performing your auth flow within your Resolve() method in your schema.
Instead, have it as your middleware before letting your router dispatching that request to your GraphQL handler.

I've created a simple gist example of a GraphQL server using net/http and graphql-go/handler, with a custom JWT auth flow (It is a typical net/http middleware pattern, this could be adapted to other custom middlewares that you might need)

Example of using graphql-go/handler with a custom JWT middleware
https://gist.github.com/sogko/07c3ac863e2ab144781b

You can even use this approach to inject context objects into the ctx context.Context and make them available inside of Resolve() (For example, global objects like DB connection pool) (
Slightly more convoluted, but I can provide a working example using chi )

It might be a good idea to have examples of how to use graphql-go/handler in different scenarios.
( I would be glad to accept any PR for that! =) )

Cheers! 🍻


In case you still want to inject custom values into the rootValue object, I've provided an example of how to create your custom GraphQL handler, taking advantage of the exposed handler.NewRequestOptions() to parse http.Request

Creating custom graphql-go/handler using handler.NewRequestOptions() to parse http.Requests
https://gist.github.com/sogko/a622e1aa5a1e022c2228

@piinecone
Copy link
Author

@sogko Thanks for your response, the gist, and these great packages!

That's a much nicer approach to handling the authorization header. Regarding contexts, do you prefer passing the db through a context and resolving it? Currently, I pass an env instance into the handler, like this:

// routes.go
h := handler.New(&handler.Config{
    Schema: graphql.GraphQLSchema(env.db),
    Pretty: true,
})
// ...

// schema.go
func GraphQLSchema(db *data.DB) *graphql.Schema {
  // db.GetViewer(), etc
}

It works, but I'd prefer to be idiomatic.

Thanks, and feel free to close this one, I think I've sufficiently derailed us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants