question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JWT token issue in HTTP Header

See original GitHub issue

API Platform version(s) affected: 2.5.4 with api-platform/admin version 2.0.1

Description
When using JWT authentication, authorization header value is not set properly.

How to reproduce
Here is the code I use. Basically copied from https://api-platform.com/docs/admin/authentication-support/.

// App.js
import React from "react";
import {Redirect, Route} from "react-router-dom";
import {
  fetchHydra as baseFetchHydra,
  HydraAdmin,
  hydraDataProvider as baseHydraDataProvider,
  ResourceGuesser
} from "@api-platform/admin";
import parseHydraDocumentation from "@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation";

const entrypoint = process.env.REACT_APP_API_ENTRYPOINT;
const fetchHeaders = { Authorization: `Bearer ${window.localStorage.getItem("token")}` };
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
  ...options,
  headers: new Headers(fetchHeaders),
});
const apiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoint, {headers: new Headers(fetchHeaders)})
  .then(
    ({api}) => ({api}),
    (result) => {
      switch (result.status) {
        case 401:
          return Promise.resolve({
            api: result.api,
            customRoutes: [
              <Route path="/" render={() => {
                window.localStorage.getItem("token") ? window.location.reload() : <Redirect to="/login" />
              }} />
            ],
          });

        default:
          return Promise.reject(result);
      }
    },
  );
const dataProvider = baseHydraDataProvider(entrypoint, fetchHydra, apiDocumentationParser);
const authProvider = {
  login: ({username, password}) => {
    const request = new Request(entrypoint + '/login', {
      method: 'POST',
      body: JSON.stringify({"email": username, password}),
      headers: new Headers({'Content-Type': 'application/json'}),
    });
    return fetch(request)
      .then(response => {
        if (response.status < 200 || response.status >= 300) {
          throw new Error(response.statusText);
        }
        return response.json();
      })
      .then(({token}) => {
        window.localStorage.setItem('token', token);
      });
  },
  logout: () => {
    localStorage.removeItem('token');
    return Promise.resolve();
  },
  checkAuth: () => {
    return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();
  },
  checkError: error => {
    const status = error.status;
    if (status === 401 || status === 403) {
      localStorage.removeItem('token');
      return Promise.reject();
    }
    return Promise.resolve();
  },
  getPermissions: params => Promise.resolve(),
};

export default () => (
  <HydraAdmin
    authProvider={authProvider}
    entrypoint={entrypoint}
    dataProvider={dataProvider}
  >
    <ResourceGuesser name="ad_campaigns" />
  </HydraAdmin>
);

Issue 1. Before Authentication

Expected As we don’t have JWT token in localStorage, redirecting to /login page is expected.

Actual Gives 403 error from sending {Authorization: Bearer null} Headers Screen Shot 2020-02-19 at 9 51 30 AM

Possible Solution
Update fetchHeaders variable like this.

// old
const fetchHeaders = { Authorization: `Bearer ${window.localStorage.getItem("token")}` };
// new
const fetchHeaders = () => {
  if (window.localStorage.getItem("token")) {
    return {Authorization: `Bearer ${window.localStorage.getItem("token")}`};
  }
  return {}
}

Issue 2. Failure After Successful Login

After updating fetchHeaders variable like above, a user can see login page when localStorage token is not available. When a user login with valid credential, there comes a multiple api calls with errors.

Screenshot of login api success. It returns Response with new token value. Screen Shot 2020-02-19 at 12 55 06 PM

Screenshot of one of api call with valid Authorization token. Screen Shot 2020-02-19 at 12 55 13 PM

Screenshot of api call failure Screen Shot 2020-02-19 at 12 55 19 PM

In my example, there are four calls of ad_campaigns api after login success. One of them is success and other three are failure which gives Unhandled Rejection (Error): Unreachable resource page error.

I am not sure why there are four api calls for one entity after login. And why three of them are not sending Authorization Headers even if localStorage has token value.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:10 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
artemkozlenkovcommented, Oct 27, 2020

Hello everybody, wanted to try api-platform-admin with api-platform backend, followed simple instruction to create react project and point to my backend api like so

import './App.css';
import { HydraAdmin } from "@api-platform/admin";

function App() {
  return (
      <HydraAdmin entrypoint="http://127.0.0.1:8000" />
  );
}

export default App;

the very first time it works, but when i move it to other host location or dockerize it I also get

./node_modules/@api-platform/api-doc-parser/lib/hydra/fetchResource.js/exports.default/<
src/hydra/fetchResource.ts:16

  13 | });
  14 | //# sourceMappingURL=fetchResource.js.map

it it a bug? thanks in advance.

sorry, not a bug for me, make sure you have database pre-populated, works! worth mentioning the ‘api-platform admin’ is an adapter for ‘react-admin’ framework though looking at both may benefit

0reactions
alanpoulaincommented, Dec 4, 2020

Should be solved with https://github.com/api-platform/docs/pull/1228. Feel free to reopen if not.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best HTTP Authorization header type for JWT - Stack Overflow
The best HTTP header for your client to send an access token (JWT or any other token) is the Authorization header with the...
Read more >
JSON Web Tokens in HTTP Headers - IBM
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties...
Read more >
JSON Web Token Introduction - jwt.io
Note that if you send JWT tokens through HTTP headers, you should try to prevent them from getting too big. Some servers don't...
Read more >
How To Send JWT Token as Header - Software Testing Material
To avoid any manual copy-pasting of JWT token, we can use variables to add a script in the Tests tab of API request...
Read more >
Do I have to send a JSON Web Token to the HTTP header?
JWT is token that is used for login user without using username and Password when user session is expired then with the help...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found