2

I have 2 applications on DigitalOceans, an Express, API, and a React application. React application gets data from API. I want to make sure no one can access this API other than my React application. I'm using Ubuntu 18.04.

Yern
  • 333
  • 1
  • 10

2 Answers2

1

You could use CORS in Express which is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain.

NOTE: I'm recommending this one given your app does not require login.

First, install the library in your backend:

npm install cors

Second, setup the allowed origin:

var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: 'http://example.com',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.use(cors(corsOptions))

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for only example.com.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

You could find more examples in CORS Middleware

Willian
  • 3,011
  • 1
  • 15
  • 38
  • 1
    I have implemented CORS, thanks for mentioning that. However, I've seen in some sites that CORS can be passed easily. Is that true? – Yern Jul 23 '20 at 11:38
  • CORS is a mechanism which aims to allow requests made on behalf of you and at the same time block some requests made by rogue JS and is triggered whenever you are making an HTTP request to a different domain/sub domain/port/protocol. This mechanism prevents attackers that plant scripts on various websites (eg. in ads displayed via Google Ads) to make an AJAX call to www.yourbank.com and in case you were logged in making a transaction using *your* credentials. The browser will not allow JavaScript to access the response. – Willian Jul 25 '20 at 14:28
  • Btw, your express api exposes sensitive data to the frontend? – Willian Jul 25 '20 at 14:31
  • No, it's not sensitive data, I actually display it to the user. I have collected some data over a couple of months and the API serves it, however it serves it randomly. Like a random word generator. I have a dictionary-like data and I serve it randomly. What I want is since it took too long to collect this data, I don't want to just give out an API for someone else to use it. I guess server-side rendering fits good but then my page would need a refresh. – Yern Jul 25 '20 at 14:45
0

You'll want to look into request authorisation methods. If you only want a simple request authorisation system that does not take into account individual users, you can create an environment variable on the frontend with an auth token, and send this with every request, then only respond with data if the authToken matches the one saved on your backend.

If you have multiple users using your app I'd recommend looking into JWTs (https://jwt.io)

louis.sugar
  • 171
  • 9
  • The app is a simple one and requires no login. I've looked into adding an environment variable however I think the auth token should be at somewhere inaccessible, not inside a React app – Yern Jul 22 '20 at 18:31
  • The reason I suggested an env var is that that way you won't have to include your authToken in the source code. It's common practice for things you want to keep secret from prying eyes. It doesn't really matter where you store the secret, what you want is a secret key that gets sent with every request to the server, and validated on the backend so you can respond with a 403 if the code is invalid, instead of sending the data. You can either do that manually with every request (hardcode the secret inclusion) or use something like an axios instance to auto-add the secret to every request – louis.sugar Jul 22 '20 at 20:52