How to add Laravel username to the access log of nginx? How to add Laravel username to the access log of nginx? nginx nginx

How to add Laravel username to the access log of nginx?


I've being doing more research and found little pieces here and there to achieve an actual solution.

Description

The solution I came up with, is to use a Middleware to set a header that includes the username, then create a log format that includes the content of that header, and then clear that header so that it doesn't shows up to the user.
Note: This code is using Laravel 5.2, you may need to adjust a little for Laravel 5.3 or other version.

Set the header

Create a middleware in Laravel that sets the username in a header, like this:

<?php namespace App\Http\Middleware;use Closure;use Illuminate\Contracts\Auth\Guard;use Illuminate\Http\Request;class UserHeader{    protected $auth;    public function __construct(Guard $auth)    {        $this->auth = $auth;    }    public function handle(Request $request, Closure $next)    {        $response = $next($request);        $user = $this->auth->user();        if ($user) {            $response->headers->set('X-Username', $user->name);        } else {            $response->headers->set('X-Username', 'Anonymous');        }        return $response;    }}

Then register the middleware in app/Http/Kernel.php

protected $middleware = [    // ....    UserHeader::class,];

This would add a header like this in the response:

X-Username: Administrator

Use the header

Now, we handle this header in Nginx.
We create a log format to use that variable and we include $sent_http_x_username in the format in /etc/nginx/nginx.conf

log_format with_user_combined '$remote_addr - $sent_http_x_username [$time_local] '    '"$request" $status $body_bytes_sent '    '"$http_referer" "$http_user_agent" '    '$pipe';

Then we use that format in our access log /etc/nginx/sites-enabled/mysite.com:

access_log /var/log/nginx/access-mysite.com.log with_user_combined;

Optional

And then, we clear the header so it doesn't get passed to the user:

more_clear_headers 'X-Username';

Leaving the header there doesn't represents any security issue as long as you don't ever decide to thrust that information in any part of your logic.


This could also could be applied to other kind of data that could be useful to have included in our logs.

I hope this helps others.


I may be wrong here, but as far as I know it is not possible. The access log is written by the server (nginx) to log activity on the server, not to log specifics of the application that runs on the server.

If you need to log which users access you Laravel application, you should probably create a separate log file for that. To link entries in this "application log" (let's call it this way) with entries in the access log, you could write an algorithm that links these entries by comparing timestamps and IP addresses. I am well aware of the fact that this is not a very elegant solution, but it might be one of the fastest / easiest solutions.