今天在写API的时候突然想到个问题,如果得用自己写的API实现一些前端网站功能但是又不想让别人用你的该咋整?先来分析一下这个需求:

  1. 你得自己能在前端用
  2. 别人不能滥用

首先,对于第一个需求:自己能在前端用,那就是说访客能很轻松的获取到你的API地址从而达到滥用的目的。所以为了满足第二个需求,就得想点法子了。

我的思路是在请求API的时候带服务器传个时间参数要用于服务器验证请求的时效性。用图表表示出来如下:

流程图
流程图

为了避免伪造时间参数的可能性,在客户端请求服务端的时候时间参数需要进行双向加密,我这里为了方便用的AES-128-ECB,下面是具体实现过程

API端:

if (!isset($_GET["token"])) {
    echo "token invalid";
    exit();
}

$token = str_replace('+', '%2B', $_GET["token"]);
$result = openssl_decrypt(urldecode($token), 'AES-128-ECB', '密码', 0); 
$diff = time() - $result;

if ($diff < 60) {
    // API实现
} else {
    echo "token invalid or expired: ". $diff;
}

调用:

$token = urlencode(openssl_encrypt(time(), 'AES-128-ECB', "密码", 0));  
echo '[URL]?token='.$token

Preview页面:

<h1>API Preview Page</h1>
<i id='showtime'>token expired in [过期时间] second</i>

<div id="showtime"></div>
<br>
<?php
$token = urlencode(openssl_encrypt(time(), 'AES-128-ECB', "密码", 0));
echo "<a target='_blank' id='token' href='[URL]?token=".$token."'>Click me for preview</a>";
?>
<script>
    var div = document.getElementById("showtime");
    var left = [过期时间] - 1;
    var myTimer = setInterval (function () {
        if (left <= 0) {    
            document.getElementById("token").remove()
            div.innerHTML = '<i>token expired, <a href="javascript:location.reload();">reload this page</a></i>'
            clearInterval(myTimer);
        } else {
            div.innerHTML = '<i>token expired in ' + left-- + ' second</i>';
        }
    }, 1000); 
</script>

DEMO

Aniphase -- 动漫经典台词