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.
- The headers apache module is required (if not enabled it would raise an error)
- 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
精彩评论