我正在构建一个 api 驱动的 Laravel 5.5 应用程序。我也想使用可公开访问的 API 来处理 UI 驱动的请求。
我的问题是,在我的 api 身份验证中间件中,检测 UI 驱动的请求(ajax 请求)并允许其通过而不尝试验证 api 身份验证凭据的最佳方法是什么? (也许尝试验证 csrf 令牌?)
您可以使用中间件来添加对 CSRF 令牌的额外检查,尽管 Laravel 默认情况下会在 Web 路由上执行此操作(Doc)。
例如添加此中间件以防止除ajax之外的任何内容进行访问: 运行这个命令:
php artisan make:middleware AllowOnlyAjaxRequests
然后在中间件文件中:
namespace App\Http\Middleware;
use Closure;
class AllowOnlyAjaxRequests
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(!$request->ajax()) {
// Handle the non-ajax request
return response('', 405);
}
return $next($request);
}
}
然后将
'ajax' => \App\Http\Middleware\AllowOnlyAjaxRequests::class,
添加到 routeMiddleware
中的
app/Http/Kernel.php
数组中
(中间件文档)
为了检测通过ajax发送的请求,您可以使用
$request->ajax()
代码。
如果您想从验证 CSRF 中排除某些 URI(请谨慎操作),您可以这样做this。
在控制器中使用此代码:
function isValidCsrf(): bool
{
return (Session::token() == request()->header('X-CSRF-TOKEN')) ||
(Session::token() == request()->post('_token'));
}
然后您可以在控制器中使用此代码块:
if(request()->isMethod('POST') && isValidCsrf())
/* Do something */
elseif(request()->isMethod('GET'))
return view('....');
else
abort(405,'only "GET, POST" methods are allowed");
在您看来,您可以在ajax请求中使用它:
$.ajax({
url: 'your url',
type: 'POST',
...
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // for separate js files or scripts from your php code
'X-CSRF-TOKEN': "{{ csrf_token() }}" //for inline blade files
},/*☝️ OR 👇*/
data: {
'_token': $('meta[name="csrf-token"]').attr('content') //for separate js files or scripts from your php code
'_token': "{{ csrf_token() }}" //for inline blade files
}
...
});
您可以在
VerifyCsrfToken
中间件中从检查 CSRF 令牌中排除特定路由。
在控制器中验证请求时将其排除后,如果
$request->ajax()
返回 false
,则可以验证 CSRF 令牌。
您可以使用
Session::token()
或 csrf_token()
函数验证 CSRF 令牌。