当前位置: 首页 > 面试题库 >

如何限制网站的API用户?

聂建茗
2023-03-14
问题内容

我网站的合法用户有时会通过API请求对服务器进行锤击,从而导致不良结果。我想建立一个限制,即每5秒不超过一个API调用或每分钟不超过n个调用(尚未知道确切的限制)。显然,我可以将每个API调用记录在数据库中,并对每个请求进行计算,以查看它们是否超出限制,但是每个请求上的所有这些额外开销都无法达到目的。我可以使用哪些其他耗费资源较少的方法来建立限制?我正在使用PHP
/ Apache / Linux,这是值得的。


问题答案:

好的,没有对服务器的 任何
写操作就无法完成我所要求的操作,但是至少可以避免记录每个请求。一种方法是使用“泄漏桶”节流方法,该方法仅跟踪最后一个请求($last_api_request)和时间范围内请求数/限制的比率($minute_throttle)。泄漏的存储区永远不会重置其计数器(与每个小时都会重置的Twitter
API的油门不同),但是如果存储区已满(用户已达到限制),则他们必须等待n几秒钟以使存储区清空,然后才能发出另一个请求。换句话说,这就像一个滚动限制:如果在时间范围内有先前的请求,它们正在缓慢地从存储桶中泄漏出去;仅在您加满水桶时才限制您。

此代码段将为$minute_throttle每个请求计算一个新值。我指定了 分钟
$minute_throttle因为您可以在任何时间段(例如,每小时,每天等)添加节流阀,尽管不止一个会很快使用户感到困惑。

$minute = 60;
$minute_limit = 100; # users are limited to 100 requests/minute
$last_api_request = $this->get_last_api_request(); # get from the DB; in epoch seconds
$last_api_diff = time() - $last_api_request; # in seconds
$minute_throttle = $this->get_throttle_minute(); # get from the DB
if ( is_null( $minute_limit ) ) {
    $new_minute_throttle = 0;
} else {
    $new_minute_throttle = $minute_throttle - $last_api_diff;
    $new_minute_throttle = $new_minute_throttle < 0 ? 0 : $new_minute_throttle;
    $new_minute_throttle += $minute / $minute_limit;
    $minute_hits_remaining = floor( ( $minute - $new_minute_throttle ) * $minute_limit / $minute  );
    # can output this value with the request if desired:
    $minute_hits_remaining = $minute_hits_remaining >= 0 ? $minute_hits_remaining : 0;
}

if ( $new_minute_throttle > $minute ) {
    $wait = ceil( $new_minute_throttle - $minute );
    usleep( 250000 );
    throw new My_Exception ( 'The one-minute API limit of ' . $minute_limit 
        . ' requests has been exceeded. Please wait ' . $wait . ' seconds before attempting again.' );
}
# Save the values back to the database.
$this->save_last_api_request( time() );
$this->save_throttle_minute( $new_minute_throttle );


 类似资料:
  • 我使用GoogleAPI php客户端库访问网站管理员工具数据。当我想列出网站地图时,它出现了致命错误:未捕获的异常“Google\u Service\u exception”(403)用户没有足够的网站权限。另见:https://support.google.com/webmasters/answer/2451999.'我将服务帐户电子邮件地址添加为我网站的限制用户,但错误仍然存在。 最后我找到

  • 我有一个充当静态网站的S3 bucket,我正在使用API网关向它分发流量。我知道CloudFront在这里是一个更好的选择,但请不要建议它。这不是一个选择,由于原因我不想说。 我正在通过配置{proxy+}资源来完成我的解决方案。下图: 我想只允许从API网关代理资源访问S3网站。是否有一种方法可以为代理资源提供一个执行角色,类似于如何为资源提供一个执行角色来运行lambda函数?Lambda执

  • 我正在开发一个java程序,可以在嵌入式播放器中播放YouTube视频。问题是,大多数音乐视频都无法播放,我遇到了以下错误:“此视频包含(媒体公司名称)的内容。某些网站限制播放。” 我尝试在Chrome加载相同的URL,结果相同。https://www.youtube.com/embed/TMZi25Pq3T8 然而,经过一些研究,我很快就修复了它,安装了一个允许我添加HTTP请求头的Chrome

  • 问题内容: 我正在使用MySQL Connector / .NET,它的所有提供程序都带有FormsAuthentication。 我需要所有用户退出。该方法无法正常工作。 如何注销所有站点用户? 问题答案: 正如乔建议的那样,您可以编写一个HttpModule来使给定DateTime之前存在的任何cookie无效。如果将其放在配置文件中,则可以在必要时添加/删除它。例如, Web.config:

  • 我试图通过使用AWS Cognito、Api-Gateway和Lambda来实现电子商务应用程序后端。 要创建新项目,用户必须登录。创建项目后,记录的用户将成为项目的创建者。我已经创建了一个Item createendpoint,并为Apigatewayendpoint添加了Cognito JWT授权程序。 现在我需要实现项目更新终结点。相关的项目更新必须只允许项目的创建者使用。API可能是这样的

  • 问题内容: 我想在使用Rails构建的网站与另一个网站之间创建一个通信API,以便可以将数据库中的数据发送到该网站。因此,我的想法是在将要创建实时的地方使用node.js,因此它将在以下过程中工作。我的数据库已连接到rails,rails将其发送到redis,然后redis将其发送到node,最后node将使用socket.IO将其发送到另一个网站。 问题 :那有效吗?有没有更简单的方法? 问题答