kenprogrammer's avatar

How can I prevent mining of data from public APIs?

I'm building an e-commerce website with Laravel API and NuxtJS. As you all know products listing endpoints are always NOT under authentication since users do not need to login to browse the product catalog. Now the issue is I don't want users to send requests to the APIs using REST clients such as Postman. How can I go about this?

NB: Remember endpoints are visible on browser's network tab.

0 likes
7 replies
kenprogrammer's avatar

@Glukinho I don't want the user to be able to make even a single request via REST clients. The website is about cars and they mighty collect the stock via JSON responses. I was thinking of setting Headers and public API key but there's no safe way to store them on the client even by using Environment variables.

Glukinho's avatar
Level 31

@kenprogrammer If some information is freely accessible via browser, there is no way to reliably deny access to it. If a user is smart enough he will mimic browser requests, fake user-agent, obtain token etc and still have your information downloaded.

You can complicate his life (and save your bandwidth) using rate limiting, but can't fully prohibit downloading.

1 like
JussiMannisto's avatar

@kenprogrammer If you have a publicly available endpoint that doesn't require authentication, it can be used by bots. There's no way around it.

You can't reliably differentiate between bots and normal client calls. Bots can pass anything in the User-Agent string.

You can try rate-limiting as @glukinho suggested, and block suspicious IPs.

Any kind of client-side JS code authentication trick doesn't help, because the code is visible on the client. It could curtail simple curl scraping, but it's trivial to write an actual web scraper with something like Selenium running a headless Chromium instance.

1 like
JussiMannisto's avatar

@kenprogrammer There's already a middleware for rate limiting. You can implement your own limiter and apply that, or you can use the default implementation with parameters:

Route::get('foo')->middleware('throttle:10,1');

That allows a maximum of 10 requests with a decay time of 1 minute.

2 likes

Please or to participate in this conversation.