2015-10-29 5 views
1

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

Так я модифицировал функцией в случае социальной попытки входа,

В 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(); 
       }, 
      ) 
     ), 

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

+0

Может быть, не имеет отношения к вашему вопросу. Но [не использовать «md5» для шифрования паролей] (http://security.stackexchange.com/a/52463/57364). – Wilt

+0

@Wilt «md5» пока что, сделает его более безопасным! –

+0

Каков класс адаптера, который вы используете? – Wilt

ответ

1

Доктрина authentication классы зарегистрированы here in the module.config.php from 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' => 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(); 
+0

Выглядит потрясающе, будет реализовывать и сообщать! спасибо –

+0

@ n01ze Вы также можете расширить существующий класс адаптера Doctrine и ввести туда личность. Не уверен, что будет работать лучше ... – Wilt

+0

Как я собираюсь передать «$ identityFromSocial» на пользовательский адаптер? в вызове менеджера службы? О, я потерял –