How do you secure a web service call from a React App?

521 views Asked by At

I've just started with React to see what all the fuss is about. I was quite impressed until I came across JSON web services and security. I am trying both fetch and axios.

So have two questions and a little bit of background for context.

  • How do you access a local web service using react and avoid the "opaque" response problem.

    //react app running on http://localhost:3000
    const result = await fetch("http://localhost/api/data.php", { mode: "no-cors" });//opaque response
    //this doesn't work either, I get the cors error
    //const result = await fetch("http://localhost/api/data.php");//opaque
    const json = await result.json();
    ....
    
  • How do you secure access to your web services from a React app. Both when working locally and when deployed.

I can understand the issues and problems with CORS etc, there are loads of articles I can find telling me what the problem is and why, which I totally get. I just couldn't find anything with a solution.

Background

  • React doesn't have any (built-in) server functionality so connecting to a database isn't possible.
  • You can't seemingly have your react app on and your web service both running on http://localhost it just won't work.
  • Will I have the same problem when deployed e.g. https://myreactapp.com trying to talk to https://myreactapp.com/api (or something of that ilk).

This appears to be borne out by the fact that every single tutorial, article, and example uses either a local JSON file or an external unrelated URL to get JSON data. Also, I could not find anything that even suggests it's even possible, which then gives rise to security questions.

My go-to for security is cookies. Simple straightforward and robust. I mean if Microsoft and Google use this approach it has some mileage.

So an additional security question is

  • If your react app and your web services have to be on two different domains, how will my cookie-based security then work?

I have read and watched several hours of tutorials and articles and none explain this part. They are all great and show you how to get going with react, but I am developing the react and web service locally in tandem. I've used the same approach with C# and PHP projects and both work perfectly with no issues.

I am happy to be told I have misunderstood or I am just plain wrong, but I would ask you provide a solution or link to an article to back it up.

Obviously, if I find a solution I will post it here.

3

There are 3 answers

0
vipcxj On BEST ANSWER

You can use a reverse proxy server. If you are developing, use a dev server such as webpack-dev-server, See here, let the proxy server send the request to the secure remote sever instead of your app. In the production, you need use a production-ready reverse proxy server, such as nginx. Then for your app, no CORS issue any more.

7
Quentin On

You can't seemingly have your react app on and your web service both running on http://localhost it just won't work.

An HTTP server is quite capable of serving up different resources for different paths on the same origin.

For example, the /api/ path can be handled by some server-side programming while everything else is served up as a static file.

You then just deploy the production files (which npm run build is typically set up to generate) to a directory where that server will pick them up and set them.

This is, obviously, awkward when dealing in a local development environment when it is usually more convenient to use the React Development Server with its support for Hot Reloading et al.

In that case there are three solutions that leap to mind. In each of them you would run the two HTTP servers (API and React Development Server) on different ports (e.g. 80 and 3000).

Set up CORS for local development. This does make dealing with cookies more awkward though.

Set up the React Development Server to proxy the API using the options in the configuration file.

Do the reverse and configure your development API server to proxy to the React Development Server.

0
djack109 On

Solved the problem with this https://enable-cors.org/server_iis7.html (UPDATED TO SUPPORT POST)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, DELETE" />
                <add name="Access-Control-Max-Age" value="3600" />
                <add name="Access-Control-Allow-Headers" value="Content-Type, Origin, Cache-Control, X-Requested-With" />
                <add name="Access-Control-Allow-Credentials" value="true" />       
            </customHeaders>
    </httpProtocol>
    </system.webServer>
</configuration>

A quick IIS reset and away we go