Alexandre Lemaire Alexandre Lemaire

Capturing auth events with ZfcUser

Had a hell of a time trying to find how to tap into ZfcUser's auth event (the registration events are really well documented, but this one...).  Figured I'd write about it while the glue-it-back-hair-glue gently massaged onto my scalp dries.

I had a requirement to tap into ZFCUser's auth event to log IP addresses and times in addition to auth record ID.  At the time at which this blog post was authored, documentation was nonexistent.  If you've stumbled here, you're probably commiserating after having Googled and found dead-end StackOverflow posts!

Here's the solution!  (Assuming you've already set up a custom user, see this blog post)

In your custom user Module's (e.g., FooUser per link above) onBootstrap event, add this code: 

 

$sm = $e->getApplication()->getServiceManager();
$zfcAuthEvents = $e->getApplication()->getServiceManager()->get('ZfcUser\Authentication\Adapter\AdapterChain')->getEventManager();

$zfcAuthEvents->attach( 'authenticate', function( $authEvent ) use( $sm ){
try
{
$remote = new \Zend\Http\PhpEnvironment\RemoteAddress;
$remote->setUseProxy( true );

$mapper = $sm->get( 'auth_log_mapper' );
$log_entity = new \FooUser\Entity\UserAuthenticationLog;
$log_entity->populate(
array(
'user_id' => $authEvent->getIdentity(),
'auth_time' => new \DateTime( "now" ),
'ip_address' => $remote->getIpAddress()
)
);

$mapper->save( $log_entity );
return true;
}
catch( \Exception $x )
{
// handle it
}
});

Your mileage may vary, I left the guts of my custom user functions in there in case it helps.  The $authEvent->getIdentity() returns an integer; and if you don't return true, it breaks the chain. 

So simple, what a PITA to deciper!   Hope this helps someone - I'd be a day younger.

Read More