react icon indicating copy to clipboard operation
react copied to clipboard

[BUG] Receive 'Not Authorised' when using Custom JWT Authentication

Open jasonsegal23 opened this issue 2 years ago • 6 comments

Environment

We are running with the following setup:

  • Local FormIO Server
  • NodeJS API (Authenticates with IDS + Serves FormIO Token)
  • React Web App (Rendering FormIO Form using '@formio/react')

Hosting type

  • [ ] Form.io
  • [x] Local deployment
    • FormIO Version: 3.0.0-rc.10
    • @formio/react Version: 5.2.4-rc.1
    • formiojs version: 4.14.9
    • Frontend framework: React
    • Browser: Chrome
    • Browser version: 107

Steps to Reproduce

  1. Login + Add FormIO JWT token (formioToken) to Local Storage
  2. Load FormIO form
  3. Make FormIO request
  4. Receive 'Not Authorised' error message

Expected behavior

'formioToken' should remain in local storage and Web App should be allowed to make requests to FormIO.

Observed behavior

'formioToken' is removed from local storage once the Form is loaded and the Web App is now not authorised to make requests to FormIO.

Additional Information

Our Custom JWT auth worked with 'react-formio' v3 ('formiojs' v3). However when we moved to 'react-formio' v4 or '@formio/react' v4/5 (all using 'formiojs' v4) this bug appeared.

Our 'formioToken' is successfully placed into Local Storage, however when we load a form the 'formio.js' code errors out with 'Bad Token' here: image

The token is then removed immediately from local storage and any subsequent FormIO requests are unauthorised.

I believe it is the same issue as the one this PR is trying to solve

jasonsegal23 avatar Oct 28 '22 08:10 jasonsegal23

I did some further testing and found that FormIO JS v4.14.8 works fine, but v4.14.9 breaks with these issues

jasonsegal23 avatar Oct 31 '22 09:10 jasonsegal23

Possible solved, but we just had the same problem and solved it by checking the setting of the apiurl in the Formio Setup. Because it was not set, the request for cecking the token goes to https://api.form.io/current. And at this endpoint the token validaten failed. When we add sth like that: Formio.setApiUrl(apiUrl); where apiUrl contains the url of the correct formio Server, the error does not occur, and all things are working fine.

buecki2018 avatar Feb 13 '23 11:02 buecki2018

@buecki2018 can you show how you used it?

NeilRiver avatar Oct 20 '23 11:10 NeilRiver

Not exactly, because i am not longer involved in project. But i remember that i simply do the Formio.setApiUrl(apiUrl); before using the Formio package.

And i think possible the error isn't still exist, because its one year ago?

buecki2018 avatar Oct 20 '23 12:10 buecki2018

Not exactly, because i am not longer involved in project. But i remember that i simply do the Formio.setApiUrl(apiUrl); before using the Formio package.

And i think possible the error isn't still exist, because its one year ago?

Are we really talking about a react? I receive a token from keyсloak, then I want to authorize it in formio

import { Form } from "@formio/react";
import { useAuthContext } from "../../KeyCloakAuth";
import { useState, useEffect } from "react";

const Private = () => {
  const { getAccesToken } = useAuthContext();
  const [state, setState] = useState();
  const [isTokenStored, setIsTokenStored] = useState(false);

  useEffect(() => {
    setState(getAccesToken().access_token);
  }, []);

  const handleClick = () => {
    localStorage.setItem("formioToken", state);
    setIsTokenStored(true);
  };

  const squareStyle = {
    width: "50px",
    height: "50px",
    backgroundColor: isTokenStored ? "green" : "transparent",
    color: "white",
    border: isTokenStored ? "1px solid black" : "none",
    cursor: isTokenStored ? "pointer" : "auto",
  };

  return (
    <div
      className="root"
      style={{ display: "flex", justifyContent: "space-around" }}
    >
      <div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <button style={{ background: "red" }} onClick={handleClick}>
            Set token to localStorage
          </button>
          <div onClick={() => window.location.reload()} style={squareStyle}>
            press me
          </div>
        </div>
        <div
          style={{
            border: "1px solid #ccc",
            padding: "10px",
            width: "400px",
            overflowWrap: "anywhere",
            wordBreak: "break-all",
          }}
        >
          {state}
        </div>
      </div>
      <div>
        <h1>Private Formio</h1>
        <Form
          src={"http://localhost:3001/form/6531b369913036c9621c8d1c/submission"}
        />
      </div>
    </div>
  );
};

export default Private;

NeilRiver avatar Oct 20 '23 12:10 NeilRiver

@jasonsegal23 are you still reproducing this issue on the latest versions?

daneformio avatar Mar 27 '24 13:03 daneformio