Search code examples
javascriptreactjsauthenticationes6-promisereact-admin

Why do I not get redirected to /login when accessing a secure page?


I am recreating the issue as I am not sure if that's a bug and a previous issue created for this just disappeared =/

Description

During an upgrade from react-admin v2 to v3.3.0, I encounter issue to get redirected to /login after rewriting the authProvider

My authProvider.js contains the following methods:

export default function createAuthProvider(urls, client, options) {
  return {
    login: (params) =>  {
      return fetchLoginBatch(params, urls, client, options);
    },
    logout: (params) => params.jwt ? fetchLogout(makeRequestLogout(urls.logout, params.jwt), options) : Promise.resolve(),
    checkError: (error) => {
      const { status } = error;
      if (status === 401 || status === 403) {
        return Promise.reject();
      }
      return Promise.resolve();
    },
    checkAuth: (params) => params.jwt ? Promise.resolve() : Promise.reject(),
    getPermissions: (params) => params.jwt ? Promise.resolve(params.jwt.authorities) : Promise.resolve(),
    refreshJwt: (params) => params.jwt ? fetchRefreshJwt(makeRefreshJwtRequest(client.accessTokenUri, {
      grant_type: 'refresh_token',
      refresh_token: params.jwt.refresh_token,
    }, client), options) : Promise.resolve()
  };
}

It is as described in documentation and example

Expected

I expect to be redirected to /login.

Result

Instead, I stay on the page, checkAuth is well called and the jwt is null,

enter image description here

Possible fix

It is offered to change the redirect using an argument to rejected promise:

    checkAuth: () => localStorage.getItem('token')
        ? Promise.resolve()
        : Promise.reject({ redirectTo: '/no-access' }),

But adding Promise.reject({ redirectTo: '/login' }) doesn't help even if the code run.

I have tried to add some logging in ra-core/lib/sideEffect/auth.js:

console.log('auth');

exports.handleCheck = function (authProvider) {
    console.log('handleCheck', authProvider);

    return function (action) {
        console.log('action', action);

        var payload, meta, error_1, redirectTo, errorMessage;

        console.log('redirectTo', redirectTo, 'meta', meta);

handleCheck is called but never action, it seems that the saga is ignored somehow.

Question

  • How should client side handle permissions and checkAuth rejection params ?

  • What should I check next to see why the redirection is failing?

How does the ra-core code follow?


Solution

  • Could you kindly scrutinize this line?

    // authProvider.js
    
    // checking if request has a JWT (this might be a typo!)
    -  checkAuth: (params) => params.jwt ? Promise.resolve() : Promise.resolve(),
    
    // If not, we should reject thus triggering a redirect.
    +  checkAuth: (params) => params.jwt ? Promise.resolve() : Promise.reject(),
    

    Let me know how it works out.