我发送了一个ajax post请求,而Laravel似乎是通过为它创建一个post路由来完成的。我已经对其进行了设置,因此对于每个使用ajaxSetup的ajax请求,都会自动将一个csrf令牌放入标头中。然后,我尝试在后端捕获该标头,并验证令牌是否匹配。
在我的web路由(自动使用web中间件)中,这将按预期返回:
Route::get('/test', function() {
return csrf_token();
});
但是,当我通过AJAX发布到一个路由时,就像下面的两种方式之一:
尝试1:
Route::post('/test', 'AjaxController@test');
在AjaxController构造中,后跟视图中的警报:
var_dump(csrf_token().',hi'); die;
响应:',hi‘(csrf_token为空)。
尝试2:
Route::post('/test', ['test' => csrf_token().',hi', 'uses' => 'AjaxController@test']);
$test = $request->route()->getAction()['test'];
var_dump($test); die;
响应:',hi‘(csrf_token为空)。
我似乎遇到的情况是,在get请求中,csrf_token()被填充,而在我的post请求中,它没有被填充。
有什么想法吗?
发布于 2017-06-08 01:29:35
终于想明白了。
确实可以在ajax post请求上检查CSRF。我希望确保在他们自己的站点上的某个人不会成功地访问我的ajax端点,特别是对于另一个用户。
然而,我遇到了Laravel操作顺序的问题,Laravel设置会话的方式。我试图在构造函数中调用一个验证方法(在同一个类中),在那里我验证了CSRF,并在一个地方验证了发出请求的用户。我想这样做是为了每当有人访问这个类时,我不必在类中的每个公共方法中调用验证,我只需调用它一次。
但是,csrf_token()和一般的请求会话在我的构造中还不可用。但是,我可以在路由中调用的控制器类的方法中使用它。
例如,给定以下路由:
Route::post('/test', 'AjaxController@test');
如果我将请求注入到构造中,然后尝试引用会话(在构造中)中的任何内容,或者获取csrf_token()的值,它将抛出一个错误,因为Laravel还没有设置这些东西。但是如果我在test方法中引用这些东西中的任何一个,它就会在那里并且可以很好地使用。
有点奇怪的Laravel操作顺序问题。
发布于 2017-06-06 22:37:31
检查您的路由组,它必须将web
中间件应用为
Route::group(['middleware' => 'web'], function () {
Route::get('/test', function() {
return csrf_token();
//or return $request->session()->token();
});
});
发布于 2017-06-06 22:37:06
csrf保护由Laravel表单管理。在处理API时,它将不可用。
您应该了解一下在Laravel https://laravel.com/docs/5.4/middleware中是如何使用中间件的。
考虑为您的API使用API中间件;)
https://stackoverflow.com/questions/44392868
复制相似问题