How do I validate access to an API for only the licensed domain?

Asked

Viewed 136 times

0

I’m looking for original ideas on how to validate access to a php API for only the domain that paid for the license, since SERVER['HTTP_REFERER'] unreliable.

I created a json activation key and encrypted it, generated a decrepitation method, but that doesn’t guarantee that the key can be copied to multiple domains. Someone has already implemented something like this with an alternative solution?

  public function GerarKeyToken($tamanho = 8, $maiusculas = true, $numeros true, $simbolos = false){
    // Caracteres de cada tipo
    $lmin = 'abcdefghijklmnopqrstuvwxyz';
    $lmai = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $num  = '1234567890';
    $simb = '!@#$%*-';
    // Variáveis internas
    $retorno     = '';
    $caracteres  = '';
    // Agrupamos todos os caracteres que poderão ser utilizados
    $caracteres .= $lmin;
    if ($maiusculas) $caracteres .= $lmai;
    if ($numeros) $caracteres .= $num;
    if ($simbolos) $caracteres .= $simb;
    // Calculamos o total de caracteres possíveis
    $len = strlen($caracteres);
    for ($n = 1; $n <= $tamanho; $n++) {
      // Criamos um número aleatório de 1 até $len para pegar um dos caracteres
      $rand = mt_rand(1, $len);
      // Concatenamos um dos caracteres na variável $retorno
      $retorno .= $caracteres[$rand-1];
    }
    return $retorno;
  }

  public function Encrypt($MegaImporterLicenca){
    $key           = hash('sha256', $MegaImporterLicenca->GetKeyToken());
    $iv            = substr(hash('sha256', $MegaImporterLicenca->GetKeyToken()), 0, 16);
    $encrypt_text  = json_encode(array('id'        => $MegaImporterLicenca->GetId(),
                                       'dominio'   => $MegaImporterLicenca->GetDominio(),
                                       'cadastro'  => $MegaImporterLicenca->GetCadastro(),
                                       'expiracao' => $MegaImporterLicenca->GetExpiracao()));
    $output        = openssl_encrypt($encrypt_text, METHOD, $key, 0, $iv);
    $output        = base64_encode($output);
    return $output;
  }

  public function Decrypt($MegaImporter,$hash){
    $key    = hash('sha256', $MegaImporter->GetKeyToken());
    $iv     = substr(hash('sha256', $MegaImporter->GetKeyToken()), 0, 16);
    $output = openssl_decrypt(base64_decode($hash), METHOD, $key, 0, $iv);
    return $output;
  }
  • The question is very broad, as it depends on how the API will be consumed. If consumed only on the server, you can limit the amount of Ips at a given time. If consumed only on the browser, REFERER is a good. If it is in both, you need to limit the number of queries so that the person does not want to "split" the key (or charge per query, there does not matter where each one accesses). Your problem is not to limit access, but to receive the $ correctly for it. Transfer the value of dividing the key to the customer, the problem is solved.

  • The problem with the referer is it can be faked, it’s not safe. The api should only give you access to the domains that bought the license.I just need alternative ideas to the logic I implement. Thanks for the correction, typo.

  • As I said, if it will be consumed in the browser, is a great referer. Your client won’t be able to stop by each end user’s house to fake this. Already, if he accesses through his server, then he forges it. That’s why it depends on the case, and why in every situation there is a way to solve it. Just knowing details.

1 answer

1

You can use a Header which gives access to only a few domains... The Header is the Access-Control-Allow-Origin and you can use it according to the example below...

<?php
$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}
  • Thanks Vitor Braga for his idea, but $_SERVER['HTTP_ORIGIN'] is not sent by all browsers and is also unreliable.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.