我正在构建一个 API 驱动的 Laravel 5.5 应用程序。我还想使用可公开访问的 API 来处理 UI 驱动的请求。
我的问题是,在我的 api 身份验证中间件中,检测 UI 驱动的请求(ajax 请求(并允许它通过而无需尝试验证 api 身份验证凭据的最佳方法是什么?(也许尝试验证CSRF令牌?
您可以使用中间件添加对CSRF令牌的额外检查,尽管Laravel默认在Web路由(Doc(上这样做。
例如,添加此中间件以防止从 ajax 以外的任何内容进行访问:运行以下命令:
php artisan make:middleware AllowOnlyAjaxRequests
然后在中间件文件中:
namespace AppHttpMiddleware;
use Closure;
class AllowOnlyAjaxRequests
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $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);
}
}
,然后在 app/Http/Kernel.php
中将'ajax' => AppHttpMiddlewareAllowOnlyAjaxRequests::class,
添加到routeMiddleware
数组
(中间件文档(
要检测通过 AJAX 发送的请求,您可以使用$request->ajax()
代码。如果你想从验证CSRF中排除一些URI(谨慎地这样做(,你可以这样做。
在控制器中使用以下代码:
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
}
...
});
您可以在中间件中排除检查 CSRF 令牌VerifyCsrfToken
特定路由。
在控制器中验证请求时排除它后,如果 CSRF 令牌返回false
,则可以验证 CSRF 令牌$request->ajax()
。
您可以使用Session::token()
或csrf_token()
函数验证 CSRF 令牌。