【发布时间】:2021-05-23 06:15:07
【问题描述】:
我希望允许某些路由仅响应我的前端网站发出的请求,这意味着出于安全原因,阻止邮递员等其他来源并仅允许来自前端域的请求。
有可能吗?
例如,我有一个网页来检查链接的动态值并验证链接上的令牌是否在数据库中,我可以考虑放置验证码,以便机器人无法检查所有可能的组合,但它是不是 100% 安全的。
【问题讨论】:
我希望允许某些路由仅响应我的前端网站发出的请求,这意味着出于安全原因,阻止邮递员等其他来源并仅允许来自前端域的请求。
有可能吗?
例如,我有一个网页来检查链接的动态值并验证链接上的令牌是否在数据库中,我可以考虑放置验证码,以便机器人无法检查所有可能的组合,但它是不是 100% 安全的。
【问题讨论】:
您可以通过创建中间件来简单地做到这一点。我添加了一些更有效的方法来添加限制。
1- 创建中间件ApiBrowserRestricationMiddleware
2- 将此\App\Http\Middleware\ApiBrowserRestricationMiddleware::class 添加到
App\Http\Kernel$middleware数组
3- 在ApiBrowserRestricationMiddleware中添加代码
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class ApiBrowserRestricationMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if(in_array($request->getHost(), ['127.0.0.1']) == false)
{
return response('', 400);
}
return $next($request);
}
}
【讨论】:
如果您的主要问题是机器人获取所有组合,throttling middleware 以及使用验证码将帮助您解决这个问题。
默认情况下,您的所有 API 路由(routes/api.php)允许每个 IP 每分钟最多 60 个请求。您可以通过更改throttle:api 部分在app/Http/Kernel.php 文件中根据您自己的需要修改此金额:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
例如,将其更改为 throttle:30:1 意味着您将允许每个 ip 每分钟 30 个请求。
如果您只想限制 api 上的某些路由,您可以在其他地方使用中间件:
Route::get('my-method', MyController::class)->middleware('throttle:30:1');
如果您想完全按域进行限制,您正在寻找的可能是自定义middleware。中间件允许您检查各种请求属性(包括通过$request->getHost() 的请求主机)并阻止任何控制器或方法。
虽然 Laravel 的默认 TrustHosts 中间件提供全局主机验证,但您可以为特定路径创建自己的自定义中间件,如下所示:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class LocalOnly
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if($request->getHost() != 'localhost')
{
return response('', 400);
}
return $next($request);
}
}
注意:如果您要创建新的中间件,则需要注册它们。 Laravel 对此 here 有自己的指南。
在这个例子中,当在任何路由上使用时,Laravel 会拒绝除localhost 之外的任何主机(所以即使是127.0.0.1 也会被拒绝)
就我个人而言,我不建议这样做,因为内置节流是一种更优雅的解决方案,但如果你真的需要这样做,那就去吧。
【讨论】: