0

I use react-admin trying to access to an Restful API Node server. I can sign in, and i'm trying to list users, but i get error 401 Unauthorized.

In the request headers:

authorization: Bearer null

And the server return the error:

JsonWebTokenError: jwt malformed

On the client react-admin dataProvider.js:

const apiUrl = "http://localhost:4000/api/v1";

const token = localStorage.getItem("token");
console.log("Token: " + token);
const httpClient = (url, options = {}) => {
  if (!options.headers) {
    options.headers = new Headers({ Accept: "application/json" });
  }
  options.headers.set("Authorization", `Bearer ${token}`);

  return fetchUtils.fetchJson(url, options);
};

On the server auth.js:

const passport = require('passport');
const httpStatus = require('http-status');
const AppError = require('../utils/AppError');
const { roleRights } = require('../config/roles');

const verifyCallback = (req, resolve, reject, requiredRights) => async (err, user, info) => {
  console.log('requiredRights: ' + requiredRights + '\n Info: ' + info + '\n User: ' + user);
  if (err || info || !user) {
    return reject(new AppError(httpStatus.UNAUTHORIZED, 'Please authenticate'));
  }
  req.user = user;

  if (requiredRights.length) {
    const userRights = roleRights.get(user.role);
    console.log('userRights: ' + userRights);
    const hasRequiredRights = requiredRights.every(requiredRight => userRights.includes(requiredRight));
    if (!hasRequiredRights && req.params.userId !== user.id) {
      return reject(new AppError(httpStatus.FORBIDDEN, 'Forbidden'));
    }
  }

  resolve();
};

const auth = (...requiredRights) => async (req, res, next) => {
  console.log('RES: ' + res);
  return new Promise((resolve, reject) => {
    passport.authenticate('jwt', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(req, res, next);
  })
    .then(() => next())
    .catch(err => next(err));
};

module.exports = auth;

But sometime the token is not null in the request headers, and it's work... Why sometime the token is null?

Thanks & Regards

Ludo

Ludo
  • 103
  • 1
  • 15

1 Answers1

0

Try reading the localStorage in the httpClient, as explained in the documentation:

-const token = localStorage.getItem("token");
console.log("Token: " + token);
const httpClient = (url, options = {}) => {
+ const token = localStorage.getItem("token");
  if (!options.headers) {
    options.headers = new Headers({ Accept: "application/json" });
  }
  options.headers.set("Authorization", `Bearer ${token}`);

  return fetchUtils.fetchJson(url, options);
};

Related doc: https://marmelab.com/react-admin/Authentication.html#sending-credentials-to-the-api

François Zaninotto
  • 7,068
  • 2
  • 35
  • 56