Skip to content

Instantly share code, notes, and snippets.

@adamlundrigan
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamlundrigan/fa4c9c98aad0220bebbe to your computer and use it in GitHub Desktop.
Save adamlundrigan/fa4c9c98aad0220bebbe to your computer and use it in GitHub Desktop.
Expunge session usage from ZfcUser

To disable PHP session usage in ZfcUser you need to do two things:

  1. Override the default auth adapter (ZfcUser\Authentication\Adapter\Db) to remove three (1,2, 3) hard-coded references to the session container

    1. db.php - the stock adapter with session-storage-specific stuff removed
    2. sm_config.php - define an invokable in the service manager config
    3. zfcuser.global.php - update auth_adapters key of ZfcUser config to point to our adapter
  2. Add an onBootstrap listener to remove session storage container from ZfcUser\Authentication\Storage\Db (see Module.php)

This method is used by LdcZfcUserApigility to ditch sessions in favor of OAuth2 tokens.

<?php
namespace LdcZfcUserApigility\Authentication\Adapter;
use ZfcUser\Authentication\Adapter\Db as BaseAdapter;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Crypt\Password\Bcrypt;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
class Db extends BaseAdapter
{
/**
* Called when user id logged out
* @param AuthEvent $e event passed
*/
public function logout(AuthEvent $e)
{
$this->getStorage()->clear();
}
public function authenticate(AuthEvent $e)
{
if ($this->isSatisfied()) {
$storage = $this->getStorage()->read();
$e->setIdentity($storage['identity'])
->setCode(AuthenticationResult::SUCCESS)
->setMessages(array('Authentication successful.'));
return;
}
$identity = $e->getRequest()->getPost()->get('identity');
$credential = $e->getRequest()->getPost()->get('credential');
$credential = $this->preProcessCredential($credential);
$userObject = null;
// Cycle through the configured identity sources and test each
$fields = $this->getOptions()->getAuthIdentityFields();
while (!is_object($userObject) && count($fields) > 0) {
$mode = array_shift($fields);
switch ($mode) {
case 'username':
$userObject = $this->getMapper()->findByUsername($identity);
break;
case 'email':
$userObject = $this->getMapper()->findByEmail($identity);
break;
}
}
if (!$userObject) {
$e->setCode(AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND)
->setMessages(array('A record with the supplied identity could not be found.'));
$this->setSatisfied(false);
return false;
}
if ($this->getOptions()->getEnableUserState()) {
// Don't allow user to login if state is not in allowed list
if (!in_array($userObject->getState(), $this->getOptions()->getAllowedLoginStates())) {
$e->setCode(AuthenticationResult::FAILURE_UNCATEGORIZED)
->setMessages(array('A record with the supplied identity is not active.'));
$this->setSatisfied(false);
return false;
}
}
$bcrypt = new Bcrypt();
$bcrypt->setCost($this->getOptions()->getPasswordCost());
if (!$bcrypt->verify($credential, $userObject->getPassword())) {
// Password does not match
$e->setCode(AuthenticationResult::FAILURE_CREDENTIAL_INVALID)
->setMessages(array('Supplied credential is invalid.'));
$this->setSatisfied(false);
return false;
}
// Success!
$e->setIdentity($userObject->getId());
// Update user's password hash if the cost parameter has changed
$this->updateUserPasswordHash($userObject, $credential, $bcrypt);
$this->setSatisfied(true);
$storage = $this->getStorage()->read();
$storage['identity'] = $e->getIdentity();
$this->getStorage()->write($storage);
$e->setCode(AuthenticationResult::SUCCESS)
->setMessages(array('Authentication successful.'));
}
/**
* Returns the storage handler
*
* Non-persistent storage is used by default unless a different storage adapter has been set.
*
* @return Storage\StorageInterface
*/
public function getStorage()
{
if (null === $this->storage) {
$this->setStorage(new \Zend\Authentication\Storage\NonPersistent());
}
return $this->storage;
}
}
<?php
namespace LdcZfcUserApigility;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$sm = $e->getApplication()->getServiceManager();
$sm->get('ZfcUser\Authentication\Storage\Db')->setStorage(
new \Zend\Authentication\Storage\NonPersistent()
);
}
// ...
}
'service_manager' => array(
'invokables' => array(
'ldc-zfc-user-apigility-authentication-adapter-db' => 'LdcZfcUserApigility\Authentication\Adapter\Db',
),
),
/**
* Authentication Adapters
*
* Specify the adapters that will be used to try and authenticate the user
*
* Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
* Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
*/
'auth_adapters' => array( 100 => 'ldc-zfc-user-apigility-authentication-adapter-db' ),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment