开发者

Put username in apache access_log with PHP and without HTTP auth

In the Apache log configuration it is possible to specify that the HTTP auth user name 开发者_StackOverflow社区should be logged. Most PHP scripts have their own, cookie-based authentication. Is it possible in PHP to provide Apache with a HTTP auth username for logging purposes, even if the authentication is cookie-based? If yes, how would the code look like? If not, what are alternatives?


Apache passes data between modules in notes. If you run PHP as an Apache module, you can use apache_note() to get and set notes. You can then include the %{note_name}n log format string to write this to the access log. This will not "leak" any data back to the client.

In PHP:

apache_note( 'username', $username );

In your server configuration:

LogFormat "%h %l %{username}n %t \"%r\" %>s %b" common_with_php_username
CustomLog logs/access_log common_with_php_username


Since Apache 2.4.7 Apache allows you to copy a response-header to a note. So if you don't run PHP as an Apache module (but for instance use PHP-FPM), and you also don't want the log-value to be sent to the client (which would usually happen if you set it in a response-header), here's a way to do it:

php:

header('X-Username: '.$username);

httpd.conf:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{username}n\"" 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


A possibility is to store usernames & past session_ids somewhere else, and let the log write the cookie values in it (usually %{PHPSESSID}C), which you then can trace back.

Another option would be to send a header with the username back to the client, preferably right after your session_start:

PHP:

header('X-Php-Sess-User: '.$username);

Customlog:

%{X-Php-Sess-User}o


Short of using an Apache handler to touch the internal auth* data structures, your best bet is to resort to environment variables. You would set a top-level environment variable using apache_setenv in your PHP code

apache_setenv('USERID','jrodriguez',true);

and then write the value to the log file with a LogFormat entry in your Apache config using "%{USERID}e" instead of "%u"

LogFormat "%v:%p %h %l %{USERID}e %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" envuid_combined
CustomLog /path/to/access.log envuid_combined

Of course, the real credentials when performing actual HTTP auth would be lost forever, so consider saving %u somewhere else -- either in a new field or in a parallel log file.


I second "towr" answer about

header('X-Username: '.$username);

I though would add what made my configuration work.

  1. The headers apache module is required (if not enabled it would raise an error)
  2. The apache statements needed the always option
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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜