Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember me #136

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions Module.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ public function getServiceConfig()
{ {
return array( return array(
'invokables' => array( 'invokables' => array(
'ZfcUser\Authentication\Adapter\Db' => 'ZfcUser\Authentication\Adapter\Db', 'ZfcUser\Authentication\Adapter\Db' => 'ZfcUser\Authentication\Adapter\Db',
'ZfcUser\Authentication\Storage\Db' => 'ZfcUser\Authentication\Storage\Db', 'ZfcUser\Authentication\Adapter\Cookie' => 'ZfcUser\Authentication\Adapter\Cookie',
'ZfcUser\Form\Login' => 'ZfcUser\Form\Login', 'ZfcUser\Authentication\Storage\Db' => 'ZfcUser\Authentication\Storage\Db',
'zfcuser_user_service' => 'ZfcUser\Service\User', 'ZfcUser\Form\Login' => 'ZfcUser\Form\Login',
'zfcuser_user_service' => 'ZfcUser\Service\User',
'zfcuser_rememberme_service' => 'ZfcUser\Service\RememberMe',
), ),
'factories' => array( 'factories' => array(


Expand Down Expand Up @@ -144,6 +146,16 @@ public function getServiceConfig()
$mapper->setHydrator(new Mapper\UserHydrator()); $mapper->setHydrator(new Mapper\UserHydrator());
return $mapper; return $mapper;
}, },

'zfcuser_rememberme_mapper' => function ($sm) {
$options = $sm->get('zfcuser_module_options');
$mapper = new Mapper\RememberMe;
$mapper->setDbAdapter($sm->get('zfcuser_zend_db_adapter'));
$entityClass = new Entity\RememberMe;
$mapper->setEntityPrototype(new $entityClass);
$mapper->setHydrator(new Mapper\RememberMeHydrator());
return $mapper;
},
), ),
); );
} }
Expand Down
10 changes: 10 additions & 0 deletions config/zfcuser.global.php.dist
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ $settings = array(
*/ */
//'logout_redirect_route' => 'zfcuser/login', //'logout_redirect_route' => 'zfcuser/login',


/**
* Remember me cookie expire time
*
* How long will the user be remembered for, in seconds?
*
* Default value: 2592000 seconds = 30 days
* Accepted values: the number of seconds the user should be remembered
*/
//'cookie_expire' => 2592000,

/** /**
* Password Security * Password Security
* *
Expand Down
12 changes: 11 additions & 1 deletion data/schema.sql
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,4 +5,14 @@ CREATE TABLE user
email VARCHAR(255) DEFAULT NULL UNIQUE, email VARCHAR(255) DEFAULT NULL UNIQUE,
display_name VARCHAR(50) DEFAULT NULL, display_name VARCHAR(50) DEFAULT NULL,
password VARCHAR(128) NOT NULL password VARCHAR(128) NOT NULL
) ENGINE=InnoDB; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE remember_me (
sid VARCHAR(16) NOT NULL,
token VARCHAR(16) NOT NULL,
user_id INTEGER(11) NOT NULL,
UNIQUE KEY sid (sid,token,user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE remember_me
ADD CONSTRAINT remember_me FOREIGN KEY (user_id) REFERENCES user (user_id) ON DELETE CASCADE ON UPDATE CASCADE;
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class AdapterChainServiceFactory implements FactoryInterface
public function createService(ServiceLocatorInterface $serviceLocator) public function createService(ServiceLocatorInterface $serviceLocator)
{ {
$chain = new AdapterChain; $chain = new AdapterChain;
$adapter = $serviceLocator->get('ZfcUser\Authentication\Adapter\Db'); $session = new \Zend\Session\Container('zfcuser');
$adapter = (\ZfcUser\Service\RememberMe::getCookie() && !$session->offsetGet('forceRelogin')) ? 'ZfcUser\Authentication\Adapter\Cookie' : 'ZfcUser\Authentication\Adapter\Db';
$adapter = $serviceLocator->get($adapter);
$chain->getEventManager()->attach('authenticate', array($adapter, 'authenticate')); $chain->getEventManager()->attach('authenticate', array($adapter, 'authenticate'));
return $chain; return $chain;
} }
Expand Down
124 changes: 124 additions & 0 deletions src/ZfcUser/Authentication/Adapter/Cookie.php
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

namespace ZfcUser\Authentication\Adapter;

use Zend\Authentication\Result as AuthenticationResult;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Stdlib\ResponseInterface as Response;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;

class Cookie extends AbstractAdapter implements ServiceManagerAwareInterface
{
protected $userMapper;

protected $rememberMeMapper;

protected $serviceManager;

protected $rememberMeService;

public function authenticate(AuthEvent $e)
{
if ($this->isSatisfied()) {
$storage = $this->getStorage()->read();
$e->setIdentity($storage['identity'])
->setCode(AuthenticationResult::SUCCESS)
->setMessages(array('Authentication successful.'));
return;
}

$cookie = explode("\n", $_COOKIE['remember_me']);

$rememberMe = $this->getRememberMeMapper()->findByIdSerie($cookie[0], $cookie[1]);

if(!$rememberMe)
return false;

if($rememberMe->getToken() !== $cookie[2])
{
// H4x0r
// @TODO: Inform user of theft, change password?
$this->getRememberMeMapper()->removeAll($cookie[0]);
$this->setSatisfied(false);
return false;
}

$userObject = $this->getUserMapper()->findById($cookie[0]);

$this->getRememberMeService()->updateSerie($rememberMe);

// Success!
$e->setIdentity($userObject->getId());
$this->setSatisfied(true);
$storage = $this->getStorage()->read();
$storage['identity'] = $e->getIdentity();
$this->getStorage()->write($storage);
$e->setCode(AuthenticationResult::SUCCESS)
->setMessages(array('Authentication successful.'));

$session = new \Zend\Session\Container('zfcuser');
$session->offsetSet("cookieLogin", true);
}

/**
* Retrieve service manager instance
*
* @return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}

/**
* Set service manager instance
*
* @param ServiceManager $locator
* @return void
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
}

public function setRememberMeMapper($rememberMeMapper)
{
$this->rememberMeMapper = $rememberMeMapper;
}

public function getRememberMeMapper()
{
if (null === $this->rememberMeMapper) {
$this->rememberMeMapper = $this->getServiceManager()->get('zfcuser_rememberme_mapper');
}
return $this->rememberMeMapper;
}

public function setUserMapper($userMapper)
{
$this->userMapper = $userMapper;
}

public function getUserMapper()
{
if (null === $this->userMapper) {
$this->userMapper = $this->getServiceManager()->get('zfcuser_user_mapper');
}
return $this->userMapper;
}

public function setRememberMeService($rememberMeService)
{
$this->rememberMeService = $rememberMeService;
}

public function getRememberMeService()
{
if (null === $this->rememberMeService) {
$this->rememberMeService = $this->getServiceManager()->get('zfcuser_rememberme_service');
}
return $this->rememberMeService;
}
}
8 changes: 8 additions & 0 deletions src/ZfcUser/Authentication/Adapter/Db.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ public function authenticate(AuthEvent $e)
$this->getStorage()->write($storage); $this->getStorage()->write($storage);
$e->setCode(AuthenticationResult::SUCCESS) $e->setCode(AuthenticationResult::SUCCESS)
->setMessages(array('Authentication successful.')); ->setMessages(array('Authentication successful.'));

/**
* If the user has first logged in with a cookie,
* but afterwords login with identity/credential
* we remove the "cookieLogin" session.
*/
$session = new \Zend\Session\Container('zfcuser');
$session->offsetSet("cookieLogin", false);
} }


protected function updateUserPasswordHash($userObject, $password, $bcrypt) protected function updateUserPasswordHash($userObject, $password, $bcrypt)
Expand Down
Loading