I have 2 servers which I run as front-end and back-end server. I use rest api for calls and nginx as reverse proxy in both servers.
I want to restrict public access of back-end server (direct access), and allow access only to front-end server for api calls. Both servers have unique domain. By default if someone tries to get the url of backend server and opens, It should show some error 400 message.
I tried nginx deny and allow but not working.
What may be the best way to do this ?
Related
How i red here, if i need to send cookie from nodejs to react application both app should be on the same port. Doing this on the server: res.cookie('token', token, { httpOnly: true }); i can send the cookies on front-end if i have the same ports, but here appear the issue if the both apps are on the same port, because if i access on front end for example http://localhost:4001/login and my server also is on http://localhost:4001, i can get the 404 error, because in this way i access the server route http://localhost:4001/login not front-end. Question: So How to solve this issue when the routes mess with each other and to be able to send the cookies?
One of the solutions is to use domains instead of ports.
For this purpose you can launch an edge web server locally (for instance Nginx or Apache) with port forwarding and set mapping from your domain to your localhost.
Also, you can use one of the plenty of services that can expose your local web servers to the Internet. Probably it could be the easiest one for you. Here is the sequence of actions then you can apply to resolve the issue:
Step 1
Run frontend and backend apps on two different ports, let's say 4001 for the backend app and 4002 for the frontend app. As a result of the step, you have to be sure that both apps are up and running and accessible via ports.
Step 2
Sign up and install https://ngrok.com/ or any other service which can expose your local app to the internet with a domain.
If you will choose ngrok, my suggestion is to write a configuration file and place it in the default location. (default location of config-file depends on your OS - here is the link to the documentation: https://ngrok.com/docs#config-default-location)
Here is the example of a config file:
authtoken: // place your ngrok access token here
region: eu
tunnels:
frontend_app:
proto: http
addr: 4002
backend_app:
proto: http
addr: 4001
Don't forget to place your authtoken, to get one you have to signup.
For more information about setup ngrok, please check the official documentation: https://ngrok.com/docs#getting-started-expose
https://ngrok.com/docs#tunnel-definitions
As a result after you launch ngrok you have to get the next output in the console:
Forwarding http://569de0ddbe4c.ngrok.io -> localhost:4002
Forwarding https://93b5cdf7c53f.ngrok.io -> localhost:4001
And be able to access your local apps via generated external addresses.
Step3
The last two things you have to do are:
Replace your API endpoint with an external URL (https://93b5cdf7c53f.ngrok.io in my example) in your frontend app.
Tweak res.cookie call in the backend app to make possible access cookies from both domains: res.cookie('token', token, { httpOnly: true , domain: 'ngrok.io' })
That's it. Now your apps are accessible from the Internet by different third-level domains with shared cookie between them.
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 currently have a node js server deployed to heroku. I want to restrict non-authorized domains from interacting with the API's. I know I can do this on the server side by either requiring authentication or by requiring specific request host. But is there a way to configure that on heroku? To only allow a specific server owned by me to call the node serer.
Heroku most likey adds an x-forwarded-for header to requests it is sending to your application. You'll want to get the first address in that list:
const ip = (req.headers['x-forwarded-for'] || '').split(',')[0];
Where req is a request object. This glitch demonstrates it in action.
Using this address, you can respond to traffic depending on its IP from your node server.
I find myself in a bit of a dilemma. I am preparing to push code out to a test server (out in the wilds of the Internet) which handles user registration and authentication (using Express + Passport) for acceptance testing.
However, I would like to be able to restrict access to the test server to those users who will be performing testing. I know node does not support an .htpasswd file mechanism but looking for another way to restrict users from accessing the server even before the application authentication process begins.
All thoughts welcome!
You can restrict via IP address in your application, or the server's firewall. If you have a reverse proxy like nginx in front of node, then you can set it up to require basic authentication via an htpasswd-like file.
I have a public facing web service that has a token based security system. Log in is accomplished by providing a username & password and a unique token is returned that is used going forward whenever the service is called.
My question is this: Is there a secure way to differentiate between a call coming from outside our internal network and a call coming from within? I would like to provide elevated privileges to clients that are calling the service from within our internal network. Specifically we have a website running on the same network as our webservices and I would like to give the website elevated privileges when calling our service.
Is there a secure way to do this when the web service is public facing? What I don't want to happen is that someone from outside our internal network to somehow get access to elevated privileges.
The services were implemented using Java and the CXF framework.
Definitely possible, here's how I would suggest doing it.
Have an reverse proxy that sits between your application and the external clients. This reverse proxy would authenticate the token and the set required privileges in the request header.
Elevating privileges for internal clients can be done by following approaches
Set an authenticate header in the requests on the reverse proxy. IF this header is set to true, it signals that the call is from an external client. The app can decide if needs to authorize based on this header. Internal clients can call this service without having to go through any authentication/authorization. Note that this would complete eliminate any auth for internal clients.
Have rules on the RP that can set additional headers containing elevated privileges based on the IP of callers. Internal clients IP can be made into a list for which this applies.
Have two endpoints for internal and external clients with revers proxies on both of them. The internal would set elevated privileges in the request headers.
You have options, I can think of at least 2 approaches immediately.
1) Also require an API key to access your webservices, and special-case the access provided to the website based on its key.
2) Elevate privs based on IP address of the requestor (website, or internal network).