发布到路由时,Laravel 5.4 null csrf_token()

时间:2017-06-06 14:33:08

标签: php laravel

我正在发送一个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(),它不是。

有什么想法吗?

4 个答案:

答案 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操作顺序问题。