无法使用 PHP slim 框架检索所有请求 headers
Cannot retrieve all request headers using PHP slim framework
我正在为个人项目使用 PHP slim 框架。出于某种原因,Slim 中 Request 的 PSR 实现显然正在过滤一些 headers。我正在尝试设置自定义 CSRF 令牌,但无法通过 $request->getHeaders() 使用。这是一个说明问题的示例:
$app->get('/bar', function ($request, $response, $args) {
echo "PHP's getallheaders() <br>";
foreach (getallheaders() as $name => $value) {
echo "$name: $value <br>";
}
echo "Slim's GetHeaders() <br>";
foreach ($request->getHeaders() as $name => $values) {
foreach ($values as $value) {
echo "$name: $value <br>";
}
}
});
我得到这个输出:
PHP's getallheaders()
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: null
Accept-Encoding: gzip, deflate
csrf_name: csrf56fc038c2f6eb
csrf_value: 4e077c04dadf22377da2aebc1a8caa78
Cookie: PHPSESSID=41016nbag70gi6shq4u2tg0aq1
Connection: keep-alive
Slim's GetHeaders()
Host: localhost
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: null
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_COOKIE: PHPSESSID=41016nbag70gi6shq4u2tg0aq1
HTTP_CONNECTION: keep-alive
我想了解为什么自定义 headers:
csrf_name: csrf56fc038c2f6eb
csrf_value: 4e077c04dadf22377da2aebc1a8caa78
正在被 Slim 删除。
信不信由你,问题在于 Slim 不喜欢 user-defined header 中的下划线。一旦我将 csrf_name 更改为 csrfname 它就起作用了:
PHP's getallheaders()
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: null
Accept-Encoding: gzip, deflate
csrfvalue: 4e077c04dadf22377da2aebc1a8caa78
csrfname: csrf56fc038c2f6eb
Cookie: PHPSESSID=5aom8b5q7ottorc9279q9sh4g1
Connection: keep-alive
Slim's GetHeaders()
Host: localhost
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: null
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_CSRFVALUE: 4e077c04dadf22377da2aebc1a8caa78
HTTP_CSRFNAME: csrf56fc038c2f6eb
HTTP_COOKIE: PHPSESSID=5aom8b5q7ottorc9279q9sh4g1
HTTP_CONNECTION: keep-alive
所以,别忘了,去掉下划线!!
编辑 正如 Mika Tuupola 所解释的,根本原因是 HTTP 服务器而不是 slim。
它不是 Slim,它是网络服务器。
即使 header 的名称包含下划线在 HTTP 规范中是有效的,但出于安全原因,Nginx and Apache 都会默默地删除那些 header。一般来说,您应该只使用包含 a..zA..Z
和 -
个字符的 header。
使用 Apache,您仍然可以使用 getallheaders()
(apache_request_headers()
.
的别名)访问名称中带有下划线的 header
使用 Nginx,您可以通过 underscores_in_headers on
设置在其名称中启用带有下划线的 headers。
我正在为个人项目使用 PHP slim 框架。出于某种原因,Slim 中 Request 的 PSR 实现显然正在过滤一些 headers。我正在尝试设置自定义 CSRF 令牌,但无法通过 $request->getHeaders() 使用。这是一个说明问题的示例:
$app->get('/bar', function ($request, $response, $args) {
echo "PHP's getallheaders() <br>";
foreach (getallheaders() as $name => $value) {
echo "$name: $value <br>";
}
echo "Slim's GetHeaders() <br>";
foreach ($request->getHeaders() as $name => $values) {
foreach ($values as $value) {
echo "$name: $value <br>";
}
}
});
我得到这个输出:
PHP's getallheaders()
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: null
Accept-Encoding: gzip, deflate
csrf_name: csrf56fc038c2f6eb
csrf_value: 4e077c04dadf22377da2aebc1a8caa78
Cookie: PHPSESSID=41016nbag70gi6shq4u2tg0aq1
Connection: keep-alive
Slim's GetHeaders()
Host: localhost
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: null
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_COOKIE: PHPSESSID=41016nbag70gi6shq4u2tg0aq1
HTTP_CONNECTION: keep-alive
我想了解为什么自定义 headers:
csrf_name: csrf56fc038c2f6eb
csrf_value: 4e077c04dadf22377da2aebc1a8caa78
正在被 Slim 删除。
信不信由你,问题在于 Slim 不喜欢 user-defined header 中的下划线。一旦我将 csrf_name 更改为 csrfname 它就起作用了:
PHP's getallheaders()
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: null
Accept-Encoding: gzip, deflate
csrfvalue: 4e077c04dadf22377da2aebc1a8caa78
csrfname: csrf56fc038c2f6eb
Cookie: PHPSESSID=5aom8b5q7ottorc9279q9sh4g1
Connection: keep-alive
Slim's GetHeaders()
Host: localhost
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: null
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_CSRFVALUE: 4e077c04dadf22377da2aebc1a8caa78
HTTP_CSRFNAME: csrf56fc038c2f6eb
HTTP_COOKIE: PHPSESSID=5aom8b5q7ottorc9279q9sh4g1
HTTP_CONNECTION: keep-alive
所以,别忘了,去掉下划线!!
编辑 正如 Mika Tuupola 所解释的,根本原因是 HTTP 服务器而不是 slim。
它不是 Slim,它是网络服务器。
即使 header 的名称包含下划线在 HTTP 规范中是有效的,但出于安全原因,Nginx and Apache 都会默默地删除那些 header。一般来说,您应该只使用包含 a..zA..Z
和 -
个字符的 header。
使用 Apache,您仍然可以使用 getallheaders()
(apache_request_headers()
.
使用 Nginx,您可以通过 underscores_in_headers on
设置在其名称中启用带有下划线的 headers。