laravel 4:为什么Request :: header()没有得到指定的头?

时间:2013-09-03 06:13:37

标签: php angularjs header laravel csrf-protection

我正在尝试使用以下内容获取标头值:

Request::header('csrf_token')

但是,我的firebug在标题中说我将csrf_token设置为baMDpF0yrfRerkdihFack1Sa9cchUk8qBzm0hK0C。事实上,我可以使用本机php代码获取csrf_token

getallheaders()['csrf_token']

现在问题是我正在进行XSRF保护吗?或许我所做的PHP代码有一个缺陷,我真的要使用越野车laravel 4功能

Request::header('csrf_token')

只返回空白。而我只是错过了一些东西。也许在我的Laravel 4配置等?

P.S:我正在使用AngularJS,但也许我使用的客户端并不重要。我有这个链接作为我的向导:How to send csrf_token() inside AngularJS form using Laravel API?

5 个答案:

答案 0 :(得分:8)

我通过删除下划线来解决问题' _'在csrf_token中,所以它将是crsftoken。

Request::header('csrf_token'); // Not working

Request::header('csrftoken'); // Working!

答案 1 :(得分:2)

我认为存在的问题是,在您使用的How to send csrf_token() inside AngularJS form using Laravel的以下答案中,csrf_token不会在XMLHttpRequest的标头中发送,而是以自己的形式发送。

然后,您需要在laravel后端中将其作为常规输入字段进行过滤。请参阅下面的工作示例:

Route::filter('csrf_json', function()
{
    if (Session::token() != Input::get('csrf_token'))
    {
        throw new Illuminate\Session\TokenMismatchException;
    }
});

<强>更新

如果你想在Angular中使用标题,你宁愿写一些像:

$httpProvider.defaults.headers.common['Authorization'] = TOKEN;

为了向XMLHttpRequests添加新标头。然后它很容易捕获,即使使用原始的PHP,如:

$aHeaders = getallheaders();
if (Session::token() != $aHeaders['authorization']) etc.

答案 2 :(得分:2)

<强>问题

使用Request::header()方法检索时,Laravel正在删除名称中带下划线的标头。此外,所有标题名称都在Request::header()方法中转换为小写。

简短解决方案

在前端,用破折号替换标题名称中的所有下划线。 csrf_token变为csrf-token

长期解决方案

在主页/布局上添加Laravel CSRF令牌作为角度常量。

<script>
    angular.module("myApp").constant("CSRF_TOKEN", "<?php echo csrf_token(); ?>"); 
</script>

将令牌添加为Angular中所有请求的默认标头。

angular.module("myApp").run(function($http, CSRF_TOKEN){
    $http.defaults.headers.common["csrf-token"] = CSRF_TOKEN;
})

让Laravel中的csrf过滤器检查标题中的匹配项而不是输入项。

/**
 * Check that our session token matches the CSRF request header token.
 *
 * @return json
 */
Route::filter("csrf", function() {
    if (Session::token() !== Request::header("csrf-token")) {
        return Response::json(array(
            "error" => array(
                "code"    => "403",
                "message" => "Ah ah ah, you didn't say the magic word.",
            ),
        ));
    }
}

答案 3 :(得分:1)

Request::header()确实用于retrieval of headers,但检查令牌的设置位置.. CSRF令牌应为placed into the session by Laravel,然后可以通过 Session::token() 方法。

如果查看通过调用Form::类生成的HTML,您将看到一个名为_token的隐藏元素,然后将其与会话中的令牌进行比较。您可以使用Input::get('_token')访问它,与任何其他传入的GET或POST变量一样。

...但是,所有这一切都不是必需的,因为可以通过CSRF中的预定义filters.php过滤器轻松管理,只需add that filter to the desired route or route group和你'将受到保护,而不必深入了解它的细节。

答案 4 :(得分:0)

问题出在Symfony Request对象上,该对象在Laravel框架中进行了扩展。看到这个github线程

https://github.com/laravel/framework/issues/1655#issuecomment-20595277

如果您希望将X添加到自定义http标头中,那么您的案例中的解决方案是将标头名称设置为HTTP_CSRF_TOKEN或HTTP_X_CSRF_TOKEN。