Skip to content
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

authentication using relay #294

Closed
almeynman opened this issue Sep 11, 2015 · 10 comments
Closed

authentication using relay #294

almeynman opened this issue Sep 11, 2015 · 10 comments
Labels

Comments

@almeynman
Copy link

I am currently handling authentication outside of relay with custom header set in DefaultNetworkLayer.
Is it preferred way and Is there a way to do it in relay?
I was stuck when trying to implement sign up functionality in relay: in relay there are following configs: FIELDS_CHANGE, NODE_DELETE, RANGE_ADD, RANGE_DELETE. So RANGE_ADD is the only one applicable here, however I need a parent and connection for that, which I do not have for a newly created user....

@steveluscher
Copy link
Contributor

Thanks for your question!

We want to make sure to keep signal strong in the GitHub issue tracker – to make sure that it remains the best place to track issues that affect the development of Relay.

Questions like yours deserve a purpose-built Q&A forum. Would you like to post this question to Stack Overflow with the tag #relayjs? We'll be happy to answer there. Post a link to your Stack Overflow question here, to so that we don't lose track of it.

https://stackoverflow.com/questions/ask?tags=relayjs

@wincent
Copy link
Contributor

wincent commented Sep 12, 2015

I'm going to close this now, but please do comment on it with a link back to your Stack Overflow post if you do make one, @almasakchabayev.

@wincent wincent closed this as completed Sep 12, 2015
@almeynman
Copy link
Author

@dminkovsky
Copy link
Contributor

Posted a similar question, except I'm wondering how people are handling access control. Maybe I'm not imaginative enough, but I really am not really seeing this :<

@mugli
Copy link

mugli commented Nov 7, 2015

I second @dminkovsky, a sample code for handling access control with Relay will be much appreciated.

@steveluscher
Copy link
Contributor

Does @kassens' answer here help? There, he demonstrates a pattern for implementing privacy at the data loader level.

@dminkovsky
Copy link
Contributor

@kassens' answer does help. Thank you @kassens.

If I may follow up here, please, because it's difficult to discuss his answer via SO comments.

@Kassen writes:

An approach that I have seen pretty successful is to bake the privacy/access control into the data model/data loader framework.

Totally makes sense. That's how I load users too and will extend this approach to the loading of all nodes.

But in order to make that happen—for example, to do User.load(id, viewer)—you need viewer at least in the root resolve methods. If so, given Relay today, the only way to get viewer into these resolve methods is through args. And to get an argument into server-side args, you must pass the parameter from the client. An example of this flow:

  • A client authenticates by some mechanism outside of Relay.
  • As part of the successful authentication, the server provides the user a token to use via HTTP request header—say a Cookie or Authorization.
  • This authentication token must then be available to Relay.Routes on the client to use in queries.
  • At the server, the token/user ID combination is validated and resolved into and "hydrated" viewer.

Such a flow seems to have the following implications:

  • The nodeDefinitions function that comes with graphql-relay-js can no longer be used because the idFetcher in that implementation only receives and object ID and not the viewer.
  • I need to decorate all my root field resolvers with a method that validates and hydrates user information.
  • The token must be available to the JS runtime. I cannot use httpOnly cookies as I've done in the past to protect the token because it needs to be available to Relay.Route.
  • The viewer as hydrated on the server then needs to be available to resolve methods further down the graph for any data loading that might be necessary deeper than the root field.

I'm only not sure about the last of these consequences. I suppose there is some "context" I can use. But I am new to this stack.

Anyway, thank you very much. What a wonderful platform.

@dminkovsky
Copy link
Contributor

This helpful post helps with my last bullet point from above, regarding the viewer being available at all depths of field resolution:

GraphQL execution systems should allow the consumer to pass some arbitrary data “through” the query, so it is accessible at any time during execution. For example, you could take some information from an HTTP request, pass it into the query, then use that information during field resolution.

The post then explains how this works.

As @mugli says, would be great to distill all of this into an example in the repository so that users can get up and running quickly and also learn these features of the stack more easily.

@dminkovsky
Copy link
Contributor

Oh, and sorry for the incremental updates—should have collected this into one follow-up post.

But, anyway, having read the post mentioned above I looked at the express-graphql source to see about getting a rootValue into the resolve methods.

I was really happy to find that you can pass an Options object to configure the middleware, and this Options object can either be the final configuration for all requests, or a function to return per-request configuration. The per-request configuration can then contain a per-request rootValue which can include the viewer above, determined from the raw request.

So this basically addresses all my questions above:

  • Regarding nodeDefinitions—no problem, the idFetcher in the default implementation gets a GraphQLResolveInfo, which includes the rootValue.
  • No need to make credentials available to the JS run time.
  • rootValue is available to all field resolution methods at all levels.

Great. Thank you!

@jkettmann
Copy link

If anyone has problems with this topic: I made an example repo for Relay/GraphQL/express authentication. It saves session data (userId and role) in a cookie using express middleware and a GraphQL Mutation

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

No branches or pull requests

6 participants