Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentication and privileges on Relay/GraphQL

Facebook does not mention authentication for their GraphQL library.

Suppose I have a users table fetchable from GraphQL and I do not wish to disclose users information to anybody who demands it except the logged in user, at what level should I add the authentication layer ?

At the schema level by mutating a "logged-in" state ?

Or maybe by passing extra parameters to the graphql function that currently takes only query and schema ?

like image 840
Lyes BEN Avatar asked Jan 14 '16 18:01

Lyes BEN


3 Answers

It's possible to add auth header with token to your GraphQL queries.

var token = localStorage.getItem('id_token');

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://pathtohost/graphql', {
    headers: {
      Authorization: token
    }
  })
);
like image 160
Tom Craft Avatar answered Oct 22 '22 21:10

Tom Craft


This blog post https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.cpmrcqcyt describes 3 types of authentication with Relay.

1 - based on a token (https://stackoverflow.com/a/34843562/2628278) - This one scales better \o/

2 - based on rootValue (https://stackoverflow.com/a/36001558/2628278)

3 - based only in Relay and GraphQL

The problem with the first two approaches is that you need to use non-relay/graphql code to handle this.

The third approach is like this:

{
  viewer(token: String) {
    name
  }
}

pass the auth token to viewer, and let graphql handles it

you will need a mutation as well:

mutation {
  createToken(username: String!, password: String!) {
    token
    error
  }
}

that will return the token or an error. The token should be stored in a cookie or local storage on web, and on AsyncStorage on React Native

like image 25
Sibelius Seraphini Avatar answered Oct 22 '22 21:10

Sibelius Seraphini


Although it's really unclear in the documentation, in addition to schema and query (or requestString as it's called in the docs), you can also pass a rootValue. That value will be passed to every resolve function in your GraphQL schema, so it's where you want to put any authentication information that is paired with the request.

For example if you call graphql with:

graphql(schema, query, auth, variables)

In your resolve functions you'll have access to auth:

async user(auth, args) {
  return await db.users.find(auth, args.id)
}
like image 2
Ian Storm Taylor Avatar answered Oct 22 '22 21:10

Ian Storm Taylor