5

我正在尝试通过以下方式获取标头值:

Request::header('csrf_token')

不过,我的萤火虫在标题中说我将 csrf_token 设置为baMDpF0yrfRerkdihFack1Sa9cchUk8qBzm0hK0C. 事实上,我可以csrf_token用原生 php 代码来代替:

getallheaders()['csrf_token']

现在的问题是我在做我的 XSRF 保护吗?或者我做的那个 php 代码有一个缺陷,我真的必须使用有问题的 laravel 4 函数

Request::header('csrf_token')

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

PS:我正在使用 AngularJS,但也许我使用什么客户端并不重要。我有这个链接作为我的指南:How to send csrf_token() inside AngularJS form using Laravel API?

4

5 回答 5

8

我通过删除 csrf_token 中的下划线“_”解决了这个问题,所以它会改为 crsftoken。

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

Request::header('csrftoken'); // Working!
于 2014-10-07T16:59:24.630 回答
2

问题

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

简短的解决方案

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

长解决方案

在主页/布局中添加 Laravel CSRF 令牌作为 Angular 常量。

<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;
})

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

/**
 * 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.",
            ),
        ));
    }
}
于 2015-01-20T23:14:57.700 回答
2

我认为问题在于,在如何使用您使用的 Laravel 在 AngularJS 表单中发送 csrf_token()的以下答案中,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.
于 2014-05-12T05:31:10.240 回答
1

Request::header()确实是用来获取 headers 的,但是检查一下 token 是在哪里设置的。 CSRF token 应该被Laravel 放到 session 中,然后可以通过Session::token()方法访问。

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

...但是,所有这些都不是必需的,因为它可以通过 中的预定义CSRF过滤器轻松管理filters.php,只需将该过滤器添加到所需的路由或路由组,您就会受到保护,而无需获取进入它的细节。

于 2013-09-03T11:23:38.130 回答
0

问题在于在 Laravel 框架中扩展的 Symfony Request 对象。看到这个 github 线程

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

在您的情况下,解决方案是将标头名称设置为 HTTP_CSRF_TOKEN 或 HTTP_X_CSRF_TOKEN 如果您喜欢在自定义 http 标头前加上 X 前缀。

于 2013-10-30T00:50:41.783 回答