ZF2: Zend_Auth с Doctrine, как обойти проверку setCredentialValue, т.е. когда проверка пароля не требуется

Я реализовал модуль входа с Zend_Auth & Doctrine и работает нормально, как и ожидалось, теперь, когда я реализовал Social login тоже в модуле, в этом случае мне нужно обойти Password отметьте, что пароль не требуется в таких случаях после того, как пользователь третий сторонние поставщики (например, facebook так далее).

Поэтому я изменил функцию в случае попытки входа в систему,

В controller

$authService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
$adapter = $authService->getAdapter();
$adapter->setIdentityValue($userProfile->email);
$adapter->setCredentialValue('NA'); //  <----- I have used "NA" to notify its an social login

И в module.config.php

'doctrine' => array(
'authentication' => array(
'orm_default' => array(
'object_manager' => 'Doctrine\ORM\EntityManager',
'identity_class' => 'Account\Entity\Account',
'identity_property' => 'username',
'credential_property' => 'password',
'credential_callable' => function(Entity\Account $user, $passwordGiven) {
if($passwordGiven == 'NA')
return true;
else
return md5($passwordGiven) == $user->getHpassword();
},
)
),

он работает нормально, но я не уверен, что это правильный способ сделать это? Любое предложение или более реальный способ сделать это.

1

Решение

Учение authentication классы зарегистрированы здесь, в module.config.php от DoctrineModule:

'doctrine' => array(
'doctrine_factories' => array(
'cache'                 => 'DoctrineModule\Service\CacheFactory',
'eventmanager'          => 'DoctrineModule\Service\EventManagerFactory',
'driver'                => 'DoctrineModule\Service\DriverFactory',
'authenticationadapter' => 'DoctrineModule\Service\Authentication\AdapterFactory',
'authenticationstorage' => 'DoctrineModule\Service\Authentication\StorageFactory',
'authenticationservice' => 'DoctrineModule\Service\Authentication\AuthenticationServiceFactory',
)
)

Вы можете легко перезаписать эти конфигурации на своих собственных фабриках.

Я не уверен, как лучше всего управлять всем этим, поскольку я понятия не имею, как выглядит ваша аутентификация в вашей социальной службе. Вы можете перезаписать любую из этих фабрик и добавить свою собственную логику, чтобы ввести свой Identity из вашей службы социальной аутентификации.

Но, возможно, было бы даже лучше вообще не использовать доктрину аутентификации, а объединить оба решения аутентификации в один класс обслуживания аутентификации. Это зависит от вас.

Я могу привести пример для настройки $identity от вашего социального сервиса в хранилище аутентификации доктрины путем перезаписи класса фабрики хранилищ. Это даст вам представление, как работать с этими вещами.

В вашем приложении module.config.php перезаписать ключ для фабрики хранения вашим классом фабрики (убедитесь, что ваш модуль загружен после модуля doctrine, чтобы ключ перезаписывался при объединении конфигурации):

'doctrine' => array(
'doctrine_factories' => array(
'authenticationstorage' => 'Application\Service\Authentication\CustomStorageFactory',
)
)

Теперь создайте этот пользовательский класс в папке вашего приложения. Ваш CustomStorageFactory например, может выглядеть так:

<?php

namespace Application\Service\Authentication;

use DoctrineModule\Authentication\Storage\ObjectRepository;
use Zend\ServiceManager\ServiceLocatorInterface;
use DoctrineModule\Service\Authentication\StorageFactory;

/**
* Customized factory to inject identity from social authentication
*/
class CustomStorageFactory extends StorageFactory
{
/**
* @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator
* @return \Zend\Authentication\AuthenticationService
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
// Construct storage like normally by calling parent class
$doctrineStorage = parent::__construct($serviceLocator);

// Write the identity into the storage
$socialService = $serviceLocator->get('SocialAuthenticationService');
if($socialService->hasIdentity()){
$identity = $socialService->getIdentity();
$doctrineStorage->write($identity);
}

// return the storage
return $doctrineStorage;
}
}

Теперь вы можете сделать что-то вроде этого:

$serviceLocator= $this->getServiceLocator();
$authService = $serviceLocator->get(`Zend\Authentication\AuthenticationService`);

// Check if we have identity, if not we authenticate
if(!$authService->hasIdentity()){
$authService->authenticate();
)
$authService->getIdentity();
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]