So for whatever reason you want to track the usage of your app by your users. We’re going to do it using middleware, now for the purposes of this I’m not going to separate things out properly how we would normally, because this is a super quick tutorial.
The Problem / Situation
You need to track your app usage for audit purposes, or some other legitimate purpose.
The Super Quick Solution
The simplest possible implementation would a new middleware called AuditRequest
which would be in App\Http\Middleware
(then register it through the HttpKernel
and invoke it wherever you need it).
I’ll assume you have an audits
table and a corresponding Audit
Model
which you’ve created, set the relevant fillable attributes etc.
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$response = $next($request);
// I've pulled this out at this point, because of a point I raise in the Also Consider section
$payload = json_encode($request->all());
Audit::create([
'user_id' => $userId,
'method' => $request->getMethod(),
'url' => $request->url(),
'route' => $request->route()->getName(),
'payload' => $payload,
'ip_address' => $request->ip(),
'user_agent' => $request->userAgent() ?? 'Not Provided'
]);
return $response;
Also Consider
- Cleaning! This could log a whole load of data, and you may well want to periodically clean it, simply moving records into another data source (S3 bucket / DigitalOcean Space / MongoDb etc) and removing them from your active database can be handy
- GDPR / Data Protection Act / PCI-DSS compliance this can be a really sticky wicket, this middleware will log everything from your payload, you so may want the ability to clean / anonymise etc.
- Usefulness of the information; what we’ve done above might not be that useful, so you may end up with something a bit more like
GDPR / Data Protection Act / PCI-DSS compliance
There are going to be times when you don’t want to store the payload, in this instance you can do something like
In your controller, when you have a request that you don’t want to track
AuditRequest::doNotTrackPayload();
In your middleware;
static $trackPayload = true;
public static function doNotTrackPayload()
{
static::$trackPayload = false;
}
In the handler method above;
$payload = null;
if (static::$trackPayload === true){
$payload = json_encode($request->all());
}
Now if the static method doNotTrackPayload
is called, we’re simply going to store the $payload
as null
thus not storing, for example, passwords, card details or anything else.
Usefulness of the Information
If you’ve got a lot of audits running through, you might want something a bit easier to read; so you might want something like the below to put a friendly message as to what they did, something like “Updated their Profile” which can be called from your controller.
For me personally, I put methods on the base Controller
for parsing this information around. And you may well want to use proper SOLID techniques to implement all the above. Naturally in these Super Quick Tutorials, I’m giving you the bare minimum to achieve the job, so that you can work within your own parameters (interfaces, dependency injection, testability, etc) which are outside of the scope of these articles.
public static function setMessage(string $message)
{
static::$message = $message;
}