I recently got to setup a React-App and a seperate Node.js/express Application on a Server.
I want the React App to be able to fetch Data from the Node Application, but i dont want anyone from the outside being able to access those api calls, not from requests, neither from direct links, Postman etc.
At first i thought about using the express-ipfilter to only allow requests from the server, but i guess that wont work, since the requests will be usually come from the users ip!?
What would be the best way to enable my react application to do static api calls for its content, without exposing the api to the outside?
I am kind of lost on this, and any Help or Advice would be highly appreciated!
You can't make your app public to everyone and hide your API. The only thing you can do is allow cors only for your domain, but anyone can still copy the curl and paste it in postman.
You need an authentication to restrict the access (JWT, oauth2, cookies etc...)
Related
I've developed simple REST API using a expressJs. I'm using React as my client side application. So the problem is anyone can see my API endpoints because of react app is in client side. So they will also able to make request and fetch data from my REST API. (May be they will build their own client side apps using my API.) I've seen some question about this and couldn't find any comprehensive answer. How these kind of a security problem should be handled? Is it possible to give the access for API to only my client app? If not how huge brands that using REST API prevent that? (Also I don't have a user authenticating scenario in my product as well. People can just visit and use the website. They don't need to register).
Authentication can be a way but it can be bypassed. Another way is you can create a proxy server which strictly blocks cross origin requests, hence it blocks requests from other domains to make request to your API, and you can make your API call from that proxy server. In this way your API server endpoint will also be not compromised.
If, as you state in your comment, this is about users on your own website being allowed to use your site's API, while disallowing off-site use (e.g. other websites, wget/curl, etc) then you need to make sure to set up proper CORS rules (to disallowed cross-origin use of your API) as well as CSP rules (to prevent user-injected scripts from proxying your API), and you also make sure to only allow API calls from connections that have an active session (so even if you don't want user authentication: use a session managemer so you can tell if someone landed on your site and got a session cookie set before they started calling API endpoints).
Session management and CORS come with express itself (see https://expressjs.com/en/resources/middleware/session.html and https://expressjs.com/en/resources/middleware/cors.html), for CSP, and lots of other security layers like HSTS, XSS filtering, etc, you typically use helmet.
I was wondering if it is possible to secure an expressjs RESTful API that only a react native app and react website could access.
For exemple my server is running on port 8000, my react native app is on port 3000 and my website on port 5000. I want the server to listen only to requests coming from these ports.
Let's say I have a POST route to mydomain.com/signup I don't want users to make that post request using external websites or tools like Postman.
What would be the best way to ensure my mobile app and Web site are the only ones allowed to access my RESTful routes.
First off, you are a bit mistaken about how a request to your API works. When your react app on port 3000 makes a request to your server on port 8000, it's just a random incoming request. It doesn't "come" from port 3000. In fact, the incoming port number with be some randomly generated port with 5 or 6 digits. Outbound ports are dynamically generated by the TCP system and you can't tell what "app" it came from.
Second off, your RESTful API server is just a server on the internet. Anyone can make a request to it. Using cross origin protections, you can provide some limits about what can be done from browser Javascript (only allowing requests from your particular domain's web pages), but other requests (not from a browser) cannot be blocked this way.
So, any code jockey using any tool other than a browser can write code to your API. What someone like Google does is they require you to either have an APIKey that they issued to you or they require some login credentials (often a cookie from a previous end-user login) that identifies the user making the request as a permitted user using their system. Even with these tools, this just means that a permitted user is accessing the API, it does not mean that only your app is accessing the API. And, in fact, you can't really prevent that.
So, what most people do is they require a login or APIKey credential and they track the type of use of the API. If the use of the API seems appropriate (particularly the types and frequency of requests), then that use is permitted. If the use of the API does not seem appropriate (often too many requests over some period of time), then that particular credential or user may be blocked from accessing the service either temporarily or permanently.
Let's say I have a POST route to mydomain.com/signup I don't want users to make that post request using external websites or tools like Postman.
You cannot effectively do this. There are obstacles you can erect to make it more difficult like putting an expiring token in your web page and having your own use of the API include the token and then detecting if its a valid token, but a determined hacker will just scrape the token from the web page and still access your API using it from whatever programming tool they want.
What would be the best way to ensure my mobile app and Web site are the only ones allowed to access my RESTful routes.
You can't. Your API is on the web. Anyone with whatever credentials you require can access it.
I created MongoDB and Node.js REST API for my website. I am accessing my database data from the API and showing it on my website. I am doing these things locally on localhost.
Now I want to host my REST API. I don't have any idea regarding hosting. If I host my REST API somewhere and start getting data through its endpoints, then anybody can use those endpoints and access my data, but I want to restrict it to my website only. Meaning, that only my website can make requests to that API, no other websites can make a request. If other websites try to access it, it should show an error. How can I achieve this? Can someone please explain me step by step how do I do this?
I think you are referring to CORS. You need to set your API to have a response header like this on all requests:
Access-Control-Allow-Origin: https://yourSiteDomain.com
You can read more about it here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Other people can still access your API directly though, through postman etc.
What you need is a CSRF(cross site request forgery) token
for node js you can use
csurf : http://expressjs.com/en/resources/middleware/csurf.html
look online on how to implment it
I'm going to create an API service for my clients to use. The api is gonna return some data that will be displayed to the customers using my client's website. The api does not need any kind of user data.
I was thinking to use an api key and use it to return the relevant data. But I want to make sure that only the customers using my clients website should be able to access the api.
My question is if I use the api in the front end and expose the api key anyone will be able to use the api from their browser. I don't want that to happen. How do I authenticate this? If that's not gonna work can I use the api from my server to client server? Even then how will I authenticate the server?
I'm using nodejs and express in the backend. Any ideas? Thanks!
This is a tricky thing to do; essentially restricting public apis. At the end of the day, the web page is going to be in the user's browser on their local machine. So if they can access it from their browser, then they can access them manually too. An API key is the best approach really, but this only acts as a deterrent more than access control. Pretty much any access control type you put into a browser can be mimicked outside the browser unfortunately.
If you want to go down the route of having users login to some extent you should look into json web tokens (jwt). This doesn't need to be on a user level, and can be on a sort of session level if you prefer. This however won't restrict the user accessing the apis directly.
If your API is public, without user authentication, then there is no way to restrict the access to it.
There are many workarounds like checking for referer or creating special tokens, but it will all be stored at client-side, and a malefactor can reuse it.
It all does not make sense in general. You have already exposed your API to your clients. Even if you create a working algorithm, a malefactor can simply run your website JavaScript methods to make it work. What are you trying to protect from?
If you to restrict the access to your API, then the most proper and efficient way is to make this API back-end, so that only your webclients at server-side have access to it.
I'm trying to call one of Magento REST APIs (say products api) from a NodeJS application using a regular HTTP Request. I know that Magento APIs requires OAuth to authenticate the user/application, and this is where I'm a bit lost.
With Magento or any OAuth application, the end-user who is using the app has to click "Authorize" in order for that application to receive the token, and then the application will be able to communicate directly with Mangento APIs.
In my case, we are talking about 2 servers, Magento and NodeJS, that will talk to each other. So There is no user involve to sort of "Click" the authorize button and validate the auth request.
The point of what I'm trying to achieve is grab product data from Magento, store it in a DB, then make some changes, after that make it accessible via NodeJS REST APIs. (That is a hard requirement and I can't change it).
My question is, Do we have to write custom Magento REST APIs that doesn't require OAuth, or maybe require the regular basic HTTP Authentication (username/password). Or there is a way to use OAuth and authenticate my Node application directly?
I hope my question is clear, if not please let me know and I will try to fix it. Thanks!
After wrestling with a similar situation, I decided to use Magento's SOAP API. All you have to do as far as authentication goes is to set up an API user in the Magento backend and then use the username/password in your API calls (I think, it's been awhile). Not sure if this fits your use case but it saved me a lot of OAuth headache.