繁体   English   中英

php REST-防止在浏览器中直接访问

[英]php REST - prevent direct access in browser

我正在用PHP开发REST API服务器,计划通过客户端应用程序调用它,但是我想防止通过浏览器直接访问API。

例如,说我对“ HOST / api / article / id”进行了GET调用,它将给定ID的文章返回给客户端应用程序。 但是,当我在浏览器中键入“ HOST / api / article / id”时,不应返回该文章-我什么也不想发生(例如,只返回空页或403)。

  • 这可能吗?
  • 如果是,这是惯例吗? (我的意思是说这是人们通常想要做的事情,还是它晦涩难懂和/或违反了HTTP / REST原则,应该避免吗?)
  • 如果是,该怎么办? (在PHP / .htaccess / etc中)

我知道我可以实现某种授权(例如API密钥),而只允许对我打算做的客户端应用程序执行API。

(我对此很陌生,所以也许我的问题没有道理。也许我误解了有关REST / HTTP /无论如何工作的一些基本知识。如果可以,请告诉我。)

正常方法是:

  1. 您的客户端(使用公共密钥),从服务器请求令牌,令牌检查密钥是否有效且未列入黑名单(如果旧密钥被泄露,您可以将其过期/将其列入黑名单)
  2. 每次发送令牌
  3. 服务器仅在有令牌的情况下响应

根据您的要求,有一种简便的方法可以实现此目的。

  1. 有一个名为“ my_client”的变量,其值为true
  2. 在您的应用程序发出的每个请求中,都在标头中发送了变量。
  3. 如果标头中包含“ my_client”变量,则服务器仅服务器信息

这种方法的缺点是,这并不是真正安全的方法,因为每个人都可以看到他们提出的请求。 因此可以注意到此额外信息。

它是如此简单,您只需编写一分钟就可以完成一次测试。

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

扩展使用标头变量的概念,我们可以将其用作“半令牌”,这意味着我们将使用仅可读的随机值填充该值。

所以这个概念是这样的:

客户端->请求随机值每个请求标头中的客户端/ sets值/客户端->向服务器发出请求。

<?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;
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM