Block API access for any other resource except Frontend
Asked Answered
K

7

13

I have a route api/v1/track and I want to send some data (JSON) by given track ID, but I want to send response for only my frontend requests or my mobile app, not any other request from anywhere!

I am using Node JS and Express, I implemented some JWT config for authentication of users with tokens but I do not know how to limit this access for this route without any pre created token

app.get("/track/:ID" , (req , res) => {

    // Block forbidden requests ... 

    // If request is from my specific resource ( Frontend or App ) then : 
    res.json(something)
}) 

I just do not want to let people use my API information, I also need that before user be authenticated for sending data to my Vue SPA.

Kv answered 23/1, 2021 at 20:17 Comment(2)
If you’re trying to prevent a hacker from impersonating your app and accessing your URL directly, that is simply not possible. The best you can do is require that the caller be authenticated. Even if you use a secret key or a certificate, a hacker who has possession of your app will also have possession of the secrets.Cardiograph
I just wanna don't let people use my API information , I need that before user be authenticated for showing data to my Vue SPAKv
G
30

There is no generic way to limit the use of your API only to your own web page. An API on the web is "on the web" and any programming tool on the web can reach it.

As others have said you can implement CORs protection, but that only prevents people from accessing your API from their own Javascript in their own web pages - it does not prevent other scripts or programming tools (like curl) from accessing your API. CORs is a client-side protection that is only enforced within modern browsers. CORs does not apply to other ways your API could be accessed such as by script or other programming tools.

The only real solution here is to implement authentication for all API requests and then to protect your server from abusive use of the API. The idea behind authentication is that you require some sort of authenticated login/account before the API will serve any result. For use in your own web page, you presumably have some sort of login that can be used for the authentication.

Then, on the server, you need every API call to check for the presence of a login credential such as a verified login cookie, verified JWT token, etc...

This prevents just open use of your API, but obviously people can still make an account on your site and then use those credentials to programmatically use your API. The only way to control that is to implement server-side protections such as rate limiting to prevent any abusive use of the API that might impact the quality or responsiveness of your server.

For API servers at places like Google, they will typically require you to register for some sort of developer account and get some API access credential that you can then use with the API. As part of that, you have to agree to their terms of service and, if you violate those terms of service, they can revoke your API credential. They will also actively control your access with rate limiting and, in some cases, bandwidth usage too.

Geometric answered 24/1, 2021 at 6:50 Comment(3)
Does this mean I can have some sort of access to twitter's api without registering a developer account and taking the authentication information from the dev tools network tab ?Frostbite
@Frostbite - Yes, you can have access to whatever Twitter's web page uses. I would expect that to be different from their official API that requires a developer account and you may have to do a pretty good job pretending to be a browser.Geometric
Thanks ,this was extremely enlightening to my APIs understanding and web as general.Frostbite
P
0

You can limit the access to your server by using CORS, in other words, you can "tell to the app from which URL can get access and which methods". There is good documentation for it. On phones, it can work only for hybrid apps (Cordova/Ionic/Phonegap, etc.) because they use a browser.

Powerful answered 23/1, 2021 at 20:31 Comment(4)
@MohammadMomeni - Just so this is entirely clear to the OP, CORS only works from browsers. The API can be hit from any other type of web request tool or scripting/programming language, including things like curl. So, all CORS does is stop other web-sites from using your API from their browser-Javascript. They are still free to use your API from their server.Geometric
So, it appears that this is not really an answer to the OP's question when they ask I just do not want to let people use my API information.Geometric
@Geometric You're right , do you have any idea for limiting access from scripts too ?Kv
@MohammadMomeni - I wrote my own answer.Geometric
S
0

I have this same question, I was thinking of generating some kind of token in my frontend, that the server verifies and can only be used once, so let's say the attacker wants to hit the endpoint using a previous used token, my server would detect it has already been used thus blocking the request. In other words my frontend generates a special token each time a request is made.

Stertorous answered 4/6, 2023 at 1:20 Comment(2)
Everyone can see your front end and copy/paste the exact same functionality.Consanguinity
true, logic in frontend is not recommended for these use cases.Stertorous
O
0

We have the same requirement where we want to restrict the api's from any other sources or rather track the api's called from our own front-end and distinguish between sources of the callers.

As there are no out of box instrumentation to block or detect callers, so we are planning to formulate custom logic for detecting if the api's are called by our front-end or other sources.

We are planning to generate one time token for each api and pass the same which will be validated by the server against the same call. If the same token is reused then it will be detected as a caller from other sources trying to imitate the UI. The one time token generation logic with be devised by the development team so known to client and server only.

This way we will be able to differentiate the callers and take required steps if needed in the future course of development.

Outworn answered 11/7, 2024 at 9:41 Comment(0)
L
-1

that's a question that I was asking my self a lot, and basically what I did is every time I enter a big company website (ebay, facebook, etc...), I open the chrome devtools network tab and see what's happening there and get inspired from it but it's hard to understand what's happening (at least for me). Another solution that I implemented is that I used the Google reCaptchaV2 on my front-end (assuming that you make calls to your api only for POST/PATCH requests), so on my server I always check if the reCaptcha token is present and valid, if it's not the request got rejected.

Leger answered 3/5, 2023 at 8:0 Comment(0)
C
-2

As mentioned in @Marcos Molina's response, you have to use CORS settings in your API

Express docs are found here

below is a basic sample from a random persons project on Github

* can be replaced with your desired frontend client domain

Generic documentation on CORS here

import http from 'http';
import bodyParser from 'body-parser';
import express from 'express';
import logging from './config/logging';
import config from './config/config';
import sampleRoutes from './routes/sample';

const NAMESPACE = 'Server';
const router = express();

// ...

/** Rules of our API */
router.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');

    if (req.method == 'OPTIONS') {
        res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
        return res.status(200).json({});
    }

    next();
});

/** Routes go here */
router.use('/api/sample', sampleRoutes);

// ...

const httpServer = http.createServer(router);

httpServer.listen(config.server.port, () => logging.info(NAMESPACE, `Server is running ${config.server.hostname}:${config.server.port}`));
Comic answered 23/1, 2021 at 22:30 Comment(0)
P
-5

I guess that an option might be to limit the backend to requests only by the IP of the frontend. For example, if the frontend has an IP of "1.2.3.4" then all requests from other IPs should be blocked.

Pouliot answered 23/1, 2021 at 20:23 Comment(1)
Front-ends have varying and unknown IP addresses. So unless this is just a point to point app with only one fixed front end client, then you cannot possibly know in advance what the IP addresses would be for all legitimate clients.Geometric

© 2022 - 2025 — McMap. All rights reserved.