我正在尝试使用以下内容获取标头值:
Request::header('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?
答案 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。