【问题标题】:laravel 4: why is Request::header() not getting the specified header?laravel 4:为什么 Request::header() 没有得到指定的标头?
【发布时间】:2013-09-06 06:39:10
【问题描述】:

我正在尝试获取标题值:

Request::header('csrf_token')

不过,我的萤火虫在标题中说我将 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?

【问题讨论】:

  • 请允许我回答一个小问题:为什么您希望Request::header('csrf_token') 首先返回该标头值?仅仅因为类方法的名称?您是否查看过该方法的来源,它实际上做了什么?
  • @hakre:感谢您的评论和想法。你说的源代码?嗯,我觉得这不容易和直观。那么必须使用什么合适的功能呢?如果不是 Request::header();就像在 laravelfour 的文档中如何检索 Content-type 一样;请求::header('Content-Type');
  • 我只是想了解您选择该代码的原因。正如您的评论所示,似乎缺少某种最低限度的理解,这是此问答网站的题外话标准,因为您甚至不希望有问题的代码能够工作并重现问题。我建议您改为在 Laravel 4 论坛中询问。
  • 有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并且包含重现问题的有效代码。请参阅SSCCE.org 获取指导。
  • 好吧,那我看看。谢谢

标签: php angularjs header laravel csrf-protection


【解决方案1】:

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

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

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

【讨论】:

  • 显然 Laravel 的标题名称有下划线的问题?
  • 这也解决了我的问题。我永远不会想到这是问题所在。
【解决方案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.

【讨论】:

    【解决方案3】:

    问题

    在使用 Request::header() 方法检索标题时,Laravel 正在删除名称中带有下划线的标题。此外,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;
    })
    

    让你在 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.",
                ),
            ));
        }
    }
    

    【讨论】:

      【解决方案4】:

      Request::header()确实是用于retrieval of headers的,但是要检查token是在哪里设置的。CSRF token应该是placed into the session by Laravel,然后就可以通过Session::token()访问了 方法。

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

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

      【讨论】:

      • 你好。我不能使用 laravel 的 Form:: 类,因为我的表单是由 Angularjs 作为我的前端生成的。但这不是问题。在我的 SPA 中,我能够通过&lt;?php echo csrf_token() ?&gt; 获得该令牌,因此我在前端使用该值创建一个标头 csrf_token,然后 laravel4 将读取并匹配到 Session::token() (这很好),不过我可以通过 getallheaders()['csrf_token'];我只是想知道为什么 Request::header('csrf_token') 返回空
      • 啊,抱歉,错过了那部分!我认为 Hakre 是对的,最好加入 laravel 论坛! :)
      【解决方案5】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2019-12-19
        • 2015-11-26
        • 2021-01-05
        • 1970-01-01
        • 2020-04-16
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多