9

I am using token-based authentication and wonder how to fully tie it together in Relay Modern. I am halfway through. Any help is much appreciated. This is the setup I have:

  • At the top level inside <App /> I render the <QueryRenderer /> entry point.
  • Inside <LoginPage /> component I have a form that triggers LoginUserMutation on submit. When I provide a valid username and password combination I receive back a token:
    • I save that token in localStorage via localStorage.setItem('token', token)
    • I then want to redirect the user to the /dashboard route via history.push('/dashboard')
  • Inside createRelayEnvironment.js's fetchQuery I define how to make a network request to the GraphQL backend:
    • Here I read whether or not I have a token stored in localStorage i.e. const token = localStorage.getItem('token');
    • If the token is available I set the following header: { ..., 'authorization': 'Bearer ${token}' }. The backend is then able to authenticate the user.

Soooo goood so far. Unfortunately, there is one issue that is spoiling the picture. This setup works great when the app initializes after the token has already been stored into localStorage. Not so though, if you are currently unauthenticated without a token entry in the localStorage.

As mentioned before, imagine you are inside the LoginUserMutation, the mutation has been successful and you get a valid token back in the onComplete callback. Now what to do with it? Yes I store it inside the localStorage. But if I redirect the user to the <Dashboard /> component I am screwed. Why? - the dashboard component needs restricted data. When the app first initializes though the restricted data is not provided as no token is being sent to the GraphQL endpoint. Then later when the token is eventually available in the LoginUserMutation Relay does not actually do anything with it.

tl;dr

Q1 How can I - equipped with a valid token - trigger a refetch of data required by the <Dashboard /> component, before I send the user to /dashboard.

Q2 Is there a better way to handle authentication w/ Relay when using JSON Web Token (JWT)? In particular, what to do from the point where you receive a valid token inside the onComplete callback of LoginUserMutation?

jonathancardoso
  • 9,319
  • 6
  • 49
  • 63
soosap
  • 1,027
  • 1
  • 10
  • 28
  • Did you find any solution? With Relay Classic there used to be middleware. In Apollo there are middlewares like: networkInterface.use([{ applyMiddleware(req, next) {} }]); networkInterface.useAfter([{ applyAfterware({ response: { headers } }, next) {} }]); There is nothing in Relay modern. – sushil bansal Oct 07 '17 at 11:05

2 Answers2

1

When authentifying your user, re-creates the Relay environment. You will drop any existing cache. This is what is recommended as anyways your cache should be different depending on which user is logged in, so dropping it entirely is OK.

Pseudo-code:

class App extends PureComponent {
  state = {
    environment: createRelayEnvironment(),
  };

  login = () => {
    doLoginMutation({
      onSuccess: () => this.setState({ environment: createRelayEnvironment() }),
    })
  }

  ...
}
yachaka
  • 4,565
  • 19
  • 29
  • 1
    Doesn't seem optimal if there's data that is indifferent to which user asks for it? General dashboards, frontpages etc. – jhm Jul 27 '17 at 06:44
-1

After some tinkering found some solution which can work. I need to change my code to incorporate the below. Check this one out: https://github.com/apollographql/apollo-fetch

It can resolve the issue of middllewares with Fetch.

Updates: I tried to make it work but was unsuccessful.

sushil bansal
  • 1,172
  • 1
  • 8
  • 12
  • 1. The question is about Relay modern not Apollo. 2. That link just goes to a repo home page, not to any code that might be insightful. 3. Yeah unsuccessful – Tim Jul 18 '19 at 09:19
  • You need to check what this package is about. I was talking about middleware with Fetch1) It can be used with RM. It is a middleware. Where did you get the idea that it can not be used with RM? 2) The repo contains the code that one will need to setup middleware. Do you need any specific guidance? 3) Yeah i updated that a long ago. – sushil bansal Aug 20 '19 at 09:52