9

Is it possible to authenticate users with different roles solely trough a graphql server in combination with relay & react?

I looked around, and couldn't find much info about this topic.

In my current setup, the login features with different roles, are still going trough a traditional REST API... ('secured' with json web tokens).

Seneca
  • 2,392
  • 2
  • 18
  • 33

1 Answers1

6

I did it in one of my app, basically you just need a User Interface, this one return null on the first root query if nobody is logged in, and you can then update it with a login mutation passing in the credentials. The main problem is to get cookies or session inside the post relay request since it does'nt handle the cookie field in the request.

Here is my client mutation:

 export default class LoginMutation extends Relay.Mutation {
  static fragments = {
    user: () => Relay.QL`
      fragment on User {
        id,
        mail
      }
    `,
  };
  getMutation() {
    return Relay.QL`mutation{Login}`;
  }

  getVariables() {
    return {
      mail: this.props.credentials.pseudo,
      password: this.props.credentials.password,
    };
  }
  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        user: this.props.user.id,
      }
    }];
  }
  getOptimisticResponse() {
    return {
      mail: this.props.credentials.pseudo,
    };
  }
  getFatQuery() {
    return Relay.QL`
    fragment on LoginPayload {
      user {
        userID,
        mail
      }
    }
    `;
  }
}

and here is my schema side mutation

var LoginMutation = mutationWithClientMutationId({
  name: 'Login',
  inputFields: {
    mail: {
      type: new GraphQLNonNull(GraphQLString)
    },
    password: {
      type: new GraphQLNonNull(GraphQLString)
    }
  },
  outputFields: {
    user: {
      type: GraphQLUser,
      resolve: (newUser) => newUser
    }
  },
  mutateAndGetPayload: (credentials, {
    rootValue
  }) => co(function*() {
    var newUser = yield getUserByCredentials(credentials, rootValue);
    console.log('schema:loginmutation');
    delete newUser.id;
    return newUser;
  })
});

to keep my users logged through page refresh I send my own request and fill it with a cookie field... This is for now the only way to make it work...

Duduche
  • 445
  • 4
  • 18
  • Thanks, I'll try it tomorrow. Do you encapsulate the 'I send my own request and fill it with a cookie field' in the getUserByCredentials function? – Seneca Oct 10 '15 at 20:01
  • actually this is really the problem with relay, you do not have access to cookies under the post request. I wait until the mutation return client side and I send a brand new homemade get request with credentials to fill my cookie..., then on refresh you send the userID via your html and in your root query you pass in that userID. – Duduche Oct 10 '15 at 20:26
  • 2
    In the absence of reset functionality (which [Relay currently doesn't have](https://github.com/facebook/relay/issues/233)), doing this via Relay itself is probably not a good idea. Because Relay caches GraphQL data internally, and that data may be user-specific, you need a way to invalidate that cache on logout _or_ login. At the moment, we're recommending that people do a full page refresh when either of those events occurs. – Greg Hurrell Oct 12 '15 at 18:21