我正在发送一个ajax帖子请求,而且使用Laravel似乎是通过为它创建一个帖子路由来完成的。我已经设置好了,所以使用ajaxSetup将csrf令牌自动放入每个ajax请求的头文件中。我试图在后端捕获该标题并验证令牌是否匹配。
在我的网络路由(自动使用网络中间件)中,按预期返回:
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(),它不是。
有什么想法吗?
答案 0 :(得分:2)
检查您的路由组,它必须将web
中间件应用为
Route::group(['middleware' => 'web'], function () {
Route::get('/test', function() {
return csrf_token();
//or return $request->session()->token();
});
});
答案 1 :(得分:0)
csrf保护由Laravel Forms管理。在处理API时它将不可用。
您应该看看Laravel中如何使用中间件 https://laravel.com/docs/5.4/middleware
考虑使用API中间件为您的API;)
答案 2 :(得分:0)
如果您在转到php artisan make:auth
时运行此resources/views/layouts/app.blade.php
这里记录的<meta name="csrf-token" content="{{ csrf_token() }}">
,您会看到:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN':$('meta[name="csrf-token"]').attr('content')
}
});
在app.js
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
在5.3中有这个很酷的功能,看起来好像已经在5.4中删除了。
const windowEventsModule = new WindowEventsModule();
function init(bundle, parent, options) {
const vr = new VRInstance(bundle, 'WelcomeToVR', parent, {
...options,
nativeModules: [windowEventsModule]
});
windowEventsModule.init(vr.rootView.context);
vr.start();
return vr;
}
window.ReactVR = {init};
所以你需要做的是将csrf字段添加到每个请求中。做前两个代码片段,你会没事的。我相信的第三个可能就是Vue。
回答你的问题:不,不,不,不。 CSRF令牌我不相信是在POST请求中生成的,它是一个跨站点引用令牌,而不是身份验证令牌。如果你正在寻找像认证令牌刷新这样的东西,那么结账JWT,虽然目前laravel的JWT包有点未完成;通过一点点工作,你可以让他们工作。
https://laravel.com/docs/5.4/authentication#authentication-quickstart 1.0.*@dev非常好。然后,您可以根据请求使用他们的刷新中间件生成新令牌,但这是非常先进的,除非它用于身份验证,否则我不会打扰。
我相信Dingo(我相信另一项正在进行的工作)https://github.com/tymondesigns/jwt-auth使用上述方法
其他任何事都让我知道!
答案 3 :(得分:0)
终于想通了。
确实可以在ajax post请求中检查CSRF。我想确保他们自己网站上的某个人没有成功做任何事情,尤其是对另一个用户来说,无法点击我的ajax端点。
然而,我遇到了Laravel操作顺序问题,Laravel设置会话的方式。我试图在构造函数中调用验证方法(在同一个类中),在那里我验证了CSRF并在一个地方验证了请求用户。我想这样做,以便每当有人上课时,我都不必在课堂上的每个公共方法中调用验证,我只需要调用一次。
但是,csrf_token()和一般的请求会话在我的构造中仍然无法使用。但是,我可以在路径中调用的控制器类中的方法中使用它。
例如,给出以下路线:
Route::post('/test', 'AjaxController@test');
如果我将Request注入到构造中然后尝试引用会话中的任何内容(在构造中),或者获取csrf_token()的值,则会抛出错误,因为Laravel没有设置该东西起来了但是,如果我在测试方法中引用其中任何一个,那么它就会存在并且可用。
有点奇怪的Laravel操作顺序问题。