3

Anyone has an idea of how to include the Laravel's username of my users into the access log? I'm using Laravel 5.2 with Nginx on Ubuntu 16.04.

I know how to add data to the access log in Nginx, but, how do I pass information (in this case the username) from Laravel to Nginx in order to add that information to the access log?

Thanks

Striezel
  • 3,693
  • 7
  • 23
  • 37

2 Answers2

6

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.

-1

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.

Striezel
  • 3,693
  • 7
  • 23
  • 37
  • Never say never :) . There is always a way, I found a way, adding the response for anyone else who may need something similar. – Nestor Mata Cuthbert Sep 13 '16 at 22:25
  • Not very elegant to add a header just to remove it a few steps later, but if it works, then I guess it is OK. You should probably mark your answer as accepted answer. ;) – Striezel Sep 14 '16 at 16:40
  • I agree that the best solution would be if you could set some environment variable that the Nginx could read. But, since there is no way for that and Nginx is also a reverse proxy it does make sense, is part of Nginx jobs to handle headers. This is a technique actually very common with reverse proxies, since is pretty much the de facto way to inform things to the reverse proxy. And is definitely way better option that using cookies. – Nestor Mata Cuthbert Sep 14 '16 at 19:11
  • And, actually, in this case the username can safely remain there, no need to be removed. That is by no means compromising information and it represent no security issue at all, as that header is not being used for anything on the system other that add logging information. Is output, not input and is not trusted anywhere. – Nestor Mata Cuthbert Sep 14 '16 at 19:16