Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict PHP API for specific domains which are saved in my database

I have created an API which takes the hostkey or API_KEY and then it validates and gives back JWT token. Everything is working fine, I can't access the restricted routes without Hostkey.

ISSUE

The major issue is that what will happen if someone gives this hostkey to others as it will no longer be protected or it will be misused. So what I want to do is not only validate the hostkey but also validate the domain from which request came from. It is kind of paid service and I really want to restrict is to specific domains. Just like google does with MAP Api as if we add that map key to other domain it throws an error.

like image 355
Akhilesh Avatar asked Feb 21 '21 15:02

Akhilesh


Video Answer


2 Answers

The only way to do this is to check the origin and referrer headers.

Unfortunately, server to server this can't be done reliably as the referrer and origin headers would be set by the coder and so can be spoofed easily. For server to server calls you would be better off whitelisting IP addresses that are allowed to make calls to your APIS. In this case use something like How to get Real IP from Visitor? to get the real IP of the server and verify it against whitelisted IPs.

Assuming this is a JS call in browser and not server to server, and that you trust the browser, the only way this can really be done is by verifying the referrer and origin headers. This can still be spoofed with a browser plugin or even with a tool like Postman so I don't recommend it for high security. Here is a PHP example for verifying the origin or referrer.

$origin_url = $_SERVER['HTTP_ORIGIN'] ?? $_SERVER['HTTP_REFERER'];
$allowed_origins = ['example.com', 'gagh.biz']; // replace with query for domains.
$request_host = parse_url($origin_url, PHP_URL_HOST);
$host_domain = implode('.', array_slice(explode('.', $request_host), -2));
if (! in_array($host_domain, $allowed_origins, false)) {
    header('HTTP/1.0 403 Forbidden');
    die('You are not allowed to access this.');     
}

Optionally also CORS headers are good as commented by @ADyson Cross-Origin Request Headers(CORS) with PHP headers

like image 82
Andrew Winter Avatar answered Oct 22 '22 20:10

Andrew Winter


I would like to suggest making a quote or limit for the number of request, so when the paid API reach for 100 request the key will stop working, then the person who paid will not give the key for others. This is not perfect solution, but I would suggest it cause most API services uses it.

like image 1
Evara Avatar answered Oct 22 '22 22:10

Evara