Cancel
Showing results for 
Search instead for 
Did you mean: 

Authentication of React frontend app

Siemens Genius Siemens Genius
Siemens Genius

Hi React experts,

 

I have a React frontend app developed by a colleague that displays a UI, and fetches data using axios which it inserts in the interface. I have deployed this app to Cloud Foundry and can start it from the Launchpad. So far so good.

 

I now want to modify the app so that it fetches data from MindSphere, using the asset management and IoT time series APIs. Having read the documentation about Authentication & Authorization, I realize that for this frontend app I need to send the sessionid and x-xsrf-token, which get set as cookies according to Calling APIs from Frontend.

 

However, after searching extensively for a way to retrieve these cookies from the React app I still have found no way. The other Example provided in the docs uses express which does not seem to work together with React.

 

How do I go about implementing the authentication from React?

11 REPLIES 11

Re: Authentication of React frontend app

Legend
Legend
Unless you are using an extra layer of authentication on top of your app, you shouldn't have any issues. After login, there's a couple of cookies set by the server, one of them is the X-XSRF-TOKEN. You need to extract that cookie value in the client code and provide it as the x-xsrf-token header. Here you have a small pure js sample:
https://stackoverflow.com/a/41721631

If using Angular, you get automatic support for this since it's implemented in the core system. I don't really know React, but there must be some kind of plugin system or automatic request interception that allows you to inject the cookie on all requests (similar to what Interceptors do in Angular).

Re: Authentication of React frontend app

Siemens Genius Siemens Genius
Siemens Genius

Thanks, Diego, for the link. I think I was overcomplicating things. This is helping me get on the right path.

Re: Authentication of React frontend app

Siemens Genius Siemens Genius
Siemens Genius

In case there are others who want to use React to build a MindApp, here is what worked for me to get authentication working:

 

function getCookie(name) {
    if (!document.cookie) {
        return null;
    }
    const cookies = document.cookie.split(';').map(c => c.trim())
          .filter(c => c.startsWith(name + '='));
    if (cookies.length === 0) {
        return null;
    }
    return decodeURIComponent(cookies[0].split('=')[1]);
}


class MyPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            config: {credentials: 'include', headers: {
                "Content-Type": "application/hal+json",
                "Accept": "application/hal+json",
                "x-xsrf-token": getCookie('XSRF-TOKEN'),
                "origin": `${window.location.protocol}//${window.location.host}`
            }}
        };
    }

 

I then include the above config in each REST call. In my case I use axios:

 

        axios.get(url, this.state.config).then((response) => {
            // handle success case
        }).catch(function (error) {
            // handle error
        });

Re: Authentication of React frontend app

Legend
Legend

Great that you managed it. Just some advice: I would not do the cookie parsing myself, there's loads of good libraries for it and there's always some quirks with them :-)

Re: Authentication of React frontend app

Siemens Genius Siemens Genius
Siemens Genius

Sorry, late reply, but better late than never. Smiley Wink

 

Yes, you are right about the use of libraries. For React there is, for example, react-cookies. Thus the getting of the cookie and preparing of the headers can be simplied to:

 

import cookie from "react-cookies";

const config = {credentials: "include", headers: {
    "Content-Type": "application/hal+json",
    "Accept": "application/hal+json",
    "x-xsrf-token": cookie.load("XSRF-TOKEN"),
    "origin": `${window.location.protocol}//${window.location.host}`
}};

Re: Authentication of React frontend app

Solution Partner Experimenter Solution Partner Experimenter
Solution Partner Experimenter

Hi, 

 

I am currently trying to access the timeseries API with a React app, using the code posted above. I keep getting the following error in the browser console:

 

Refused to set unsafe header “origin”

 

Any ideas?

 

Thanks!

Re: Authentication of React frontend app

Legend
Legend
@Vegard Does that happen when you serve the website from mindsphere or are you trying to execute it locally? Browsers won't allow you to change the origin header if it doesn't match the website loaded (e.g. localhost to mindsphere).

If you are serving the website from Mindsphere, then you can basically avoid setting the header, since the browser request will be sent from the same origin as the api request and there's no CORS involved.

Re: Authentication of React frontend app

Solution Partner Experimenter Solution Partner Experimenter
Solution Partner Experimenter

I am serving the website form MindSphere. I try to do a GET request to the timeseries API as described by RobertB. As I understand from the documentation and this thread, I need to pass the xsrf-token with the URL, and this is why I access the header.

 

The error disappears if I remove “origin” from the config variable. However, I still get an error stating:

 

Refused to connect to 'https://gateway.eu1.mindsphere.io/api/iottimeseries/v3/timeseries/nnnnnn/xxxxxxx' because it violates the following Content Security Policy directive: "default-src 'self' static.eu1.mindsphere.io". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

 

Have I misunderstood anything? I only reproduce what was posted by RobertB.

 

I apologize for my limited experience in web development – your help is highly appreciated.

Re: Authentication of React frontend app

Legend
Legend

That is happening most probably because you are sending your requests to the `gateway.eu1...` endpoint and your app CORS configuration does not allow it. The easiest solution is to just modify your requests to use as host the very same host url as your app is hosted under, as documented. You can just perform this by modifying your url called in code to just a relative path like `/api/iottimeseries/...`. That way the host will be same url as your own app.

 

This is also possible when you are developing in localhost. It could always be done but it requires some "magic" in your dev setup. We will be documenting in a few days in the DevOps OSS Project how to do this easily so you can properly develop your web app running it in localhost, without requiring a full push to MindSphere. This will be for Angular though, so you will need to adapt the ideas to React.

 

Happy to help!