使用 PHP 将用户名放在 apache access_log 中,但不使用 HTTP 身份验证
Posted
技术标签:
【中文标题】使用 PHP 将用户名放在 apache access_log 中,但不使用 HTTP 身份验证【英文标题】:Put username in apache access_log with PHP and without HTTP auth 【发布时间】:2011-03-24 06:46:10 【问题描述】:在 Apache 日志配置中,可以指定应该记录 HTTP auth 用户名。大多数 php 脚本都有自己的基于 cookie 的身份验证。在 PHP 中是否可以为 Apache 提供 HTTP 身份验证用户名用于日志记录,即使身份验证是基于 cookie 的?如果是,代码会是什么样子?如果没有,有什么替代方案?
【问题讨论】:
我不认为这是个好主意。为什么不使用单独的日志文件? 因为我想用AWStats之类的工具做简单的统计。 【参考方案1】:Apache 在notes 中的模块之间传递数据。如果您将 PHP 作为 Apache 模块运行,则可以使用 apache_note()
获取和设置注释。然后,您可以包含 the %note_namen
log format string 以将其写入访问日志。这不会将任何数据“泄露”回客户端。
在 PHP 中:
apache_note( 'username', $username );
在您的服务器配置中:
LogFormat "%h %l %usernamen %t \"%r\" %>s %b" common_with_php_username
CustomLog logs/access_log common_with_php_username
【讨论】:
如果 apache_note() 没有定义用户名值会怎样? $username 崩溃日志是插入还是留空? @jedema 不确定,我认为是空白或破折号 (-
)。我现在没有设置来测试它,但如果你这样做了,你能告诉我们结果吗?
如果没有设置,它使用-
。【参考方案2】:
从 Apache 2.4.7 开始,Apache 允许您将响应标头复制到注释中。因此,如果您不将 PHP 作为 Apache 模块运行(但例如使用 PHP-FPM),并且您也不希望将日志值发送到客户端(如果您将其设置在response-header),这是一种方法:
php:
header('X-Username: '.$username);
httpd.conf:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%usernamen\"" logfmtname
vhost.conf:
CustomLog logs/vhost-access_log logfmtname
# copy response-header value to note
Header note X-Username username
# unset response-header so client won't get it
Header unset X-Username
【讨论】:
【参考方案3】:一种可能性是将用户名和过去的 session_ids 存储在其他地方,并让日志将 cookie 值写入其中(通常是%PHPSESSIDC
),然后您可以追溯。
另一种选择是将带有用户名的标头发送回客户端,最好是在您的 session_start
之后:
PHP:
header('X-Php-Sess-User: '.$username);
自定义日志:
%X-Php-Sess-Usero
【讨论】:
【参考方案4】:不使用 Apache 处理程序来处理内部 auth* 数据结构,最好的办法是求助于环境变量。您可以在 PHP 代码中使用 apache_setenv 设置***环境变量
apache_setenv('USERID','jrodriguez',true);
然后使用“%USERIDe”而不是“%u”将值写入 Apache 配置中的 LogFormat 条目的日志文件
LogFormat "%v:%p %h %l %USERIDe %t \"%r\" %>s %O \"%Refereri\" \"%User-Agenti\"" envuid_combined
CustomLog /path/to/access.log envuid_combined
当然,执行实际 HTTP 身份验证时的真实凭据将永远丢失,因此请考虑将 %u 保存在其他地方——无论是在新字段中还是在并行日志文件中。
【讨论】:
环境变量不会是全局的,因此不可靠 @Esben 不确定你的意思,但一般来说,不 - envorioment 变量不是全局的。上述解决方案非常适合我。【参考方案5】:我第二个“塔”回答一下
header('X-Username: '.$username);
虽然我会添加使我的配置工作的原因。
-
需要 headers apache 模块(如果未启用,则会引发错误)
apache 语句需要 always 选项
CustomLog logs/vhost-access_log logfmtname
# copy response-header value to note
Header always note X-Username username
# unset response-header so client won't get it
Header always unset X-Username
【讨论】:
以上是关于使用 PHP 将用户名放在 apache access_log 中,但不使用 HTTP 身份验证的主要内容,如果未能解决你的问题,请参考以下文章