awa993
awa993

Reputation: 187

php REST - prevent direct access in browser

I'm developing REST API server in PHP, which I plan to call by client application, but I want to prevent direct API accesss via browser.

E.g. say I have GET call on "HOST/api/article/id" which would return article with given id to the client application. But when I type "HOST/api/article/id" in my browser, the article shouldn't be returned - I want nothing to happen (for example just return empty page or 403).

I know I could implement some kind of authorization (like API key) instead which would allow API execution only for the client applications, which I plan to do anyway.

(I'm kind of new to this so maybe my question doesn't make sense. Maybe I misunderstood something very basic about how REST/HTTP/whatever works. If so, please tell me.)

Upvotes: 1

Views: 3066

Answers (1)

thefolenangel
thefolenangel

Reputation: 1060

The normal approach would be:

  1. Your client (using a public key), requests token from the server, token checks if key is valid and not blacklisted (you can expire/blacklist old keys if they are compromised)
  2. Token is sent every time
  3. Server only responds if there is a token

Depending what your requirements, there is a hacky way to implement this.

  1. Have a variable, called "my_client" with value true
  2. On each request from your application sent the variable in your headers.
  3. Server only servers information if "my_client" variable is in the headers

The cons with this approach is, that is not really secure, because each person can see the requests they make. Therefor can notice this extra information.

Its so simple that you can write it for a minute, just as a test.

<?php
 if(!$_SERVER['HTTP_MY_CLIENT']){
   header("HTTP/1.1 403 FORBIDEN");
  }

Extending on the concept of using a header variable, we can use it as "semi token", which will mean we will populate the value with a random value that only we can read.

So the concept is this:

Client -> Request random value Client /sets value in each request header/ Client -> makes requests to the server.

<?php
 /* A basic API token and authentication class. */
 class SimpleToken
 {
    /* Creates a salt based on the passed key that is good for the current day */
   public static function generateSalt($key)
   {
    return md5($key . date('Y-m-d'));
   }
  /* Crytographically combine the key and the salt to produce a token */
   public static function generateToken($key, $content)
   {
    $package = $content . $key;
    return crypt($package);
   }
   /* Generate a relatively strong SSL key */
  public static function generateKey()
   {
    $config = array(
        "digest_alg" => "sha512",
        "private_key_bits" => 4096,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    );
    //Create a private key
    $res = openssl_pkey_new($config);
    //Extract the private part of the key
    openssl_pkey_export($res, $private_key);
    //Shorten it up for use in an API
    return md5($private_key);
}

/* Verify the authenticity of the passed key/token pair */
public static function isAuthentic($key, $content, $token)
{
    $package = $content . $key;
    if(crypt($package, $token) == $token)
    {
        return true;
    }
    else
    {
        return false;
    }
  }
}

Upvotes: 1

Related Questions