ra-data-opencrud icon indicating copy to clipboard operation
ra-data-opencrud copied to clipboard

Authentication in react-admin

Open sen0va opened this issue 5 years ago • 5 comments

I tried to implement authentication with prisma with no success. Do you have a working example with auth?

sen0va avatar Jan 15 '19 15:01 sen0va

It uses ApolloClient so you can set authentication as you'd normally do in Apollo. Here are some exmples.

As mentioned here, you can supply your own Apollo client (once configured for authentication)


// Create and configure your own client
const myLinkWithAuthentication = { /* see Apollo docs */ };
const client = new ApolloClient({
  link: myLinkWithAuthentication
});

// Supply the Apollo client to buildOpenCrudProvider
buildOpenCrudProvider({ client });

dreglad avatar Jan 18 '19 01:01 dreglad

If you use it with a prisma token, you will receive an error message, and redirection to the login page will not occur (ra failed) I think it is because ra trying to init but getting this error (at this point, we does't have token), so he can't redirect to login page.

Uncaught (in promise) Error: GraphQL error: Your token is invalid. It might have expired or you might be using a token from a different project.
    at new ApolloError (ApolloError.js:33)
    at eval (QueryManager.js:360)
    at eval (QueryManager.js:808)
    at Array.forEach (<anonymous>)
    at eval (QueryManager.js:807)
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (QueryManager.js:803)
    at Object.next (QueryManager.js:887)
    at notifySubscription (Observable.js:152)
    at onNotify (Observable.js:196)
    at SubscriptionObserver.next (Observable.js:248)
    at eval (bundle.esm.js:98)
    at Array.forEach (<anonymous>)
    at Object.next (bundle.esm.js:97)
    at notifySubscription (Observable.js:152)
    at onNotify (Observable.js:196)
    at SubscriptionObserver.next (Observable.js:248)
    at notifySubscription (Observable.js:152)
    at onNotify (Observable.js:196)
    at SubscriptionObserver.next (Observable.js:248)
    at eval (bundle.esm.js:175)

My App.js

const authLink = setContext((_, { headers }) => {
    // get the authentication token from local storage if it exists
    const token = localStorage.getItem('token');
    // return the headers to the context so httpLink can read them
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : "",
      }
    }
  });
const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache()
  });

My authProvider.js

import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_GET_PERMISSIONS, AUTH_CHECK } from 'react-admin';
// import decodeJwt from 'jwt-decode';

export default (type, params) => {
    if (type === AUTH_LOGIN) {
        const { token } = params;
        localStorage.setItem('token', token);
    }
    if (type === AUTH_LOGOUT) {
        localStorage.removeItem('role');
        return Promise.resolve();
    }
    if (type === AUTH_ERROR) {
        debugger
    }
    if (type === AUTH_CHECK) {
        return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();
    }
    return Promise.reject('Unknown method');
};

(I also use a custom login page where I just get the token from user)

How we can resolve this issue?

MaksimKlepikov avatar Feb 12 '19 14:02 MaksimKlepikov

+1

gabrieltong avatar Mar 14 '19 02:03 gabrieltong

Doc should be improved to showcase authentication example, it's not that straightforward.

Vadorequest avatar Mar 04 '20 18:03 Vadorequest

Here's how I did it.

const httpLink = createHttpLink({
      uri: 'https://api-euwest.graphcms.com/v1/xxxxx/master',
    });

    const authLink = setContext((_, { headers }) => {
      // get the authentication token from local storage if it exists
      const token = '';
      // return the headers to the context so httpLink can read them
      return {
        headers: {
          ...headers,
          authorization: token ? `Bearer ${token}` : '',
        },
      };
    });
    const client = new ApolloClient({
      link: authLink.concat(httpLink),
      cache: new InMemoryCache(),
    });

    buildGraphQLProvider({
      client,
    }).then((dataProvider) => this.setState({ dataProvider }));

Vadorequest avatar Mar 04 '20 18:03 Vadorequest