ZfcUser перенаправляет динамический URL-адрес после входа в систему

StackOverflow https://stackoverflow.com//questions/25001558

Вопрос

Я учусь разрабатывать веб-сайт с помощью ZF2.Я скачал 2 модуля ZfcUser и BjyAuthorize.Конфигурации были довольно простыми после того, как я прочитал документацию.Однако я так и не нашел никакого решения для следующей ситуации:

Гость попадает на запись в блоге (www.yourdomain.com/blog/541) -> BjyAuthorize перенаправит гостя на страницу входа в систему -> после успешного входа перенаправляет на www.yourdomian.com/blog/541

У меня есть решение для перенаправления, когда гость прибывает в зону ограниченного доступа:

public function onBootstrap(MvcEvent $e)
{
    $app = $e->getApplication();
    $sm = $app->getServiceManager();
    $app->getEventManager()->attach(
        'route',
        function($e) {
            $app = $e->getApplication();
            $routeMatch = $e->getRouteMatch();
            $sm = $app->getServiceManager();
            $auth = $sm->get('zfcuser_auth_service');
            if (!$auth->hasIdentity() && $routeMatch->getMatchedRouteName() != 'user/login'
                && $routeMatch->getMatchedRouteName() != 'zfcuser/login') {
                $response = $e->getResponse();
                $response->getHeaders()->addHeaderLine(
                    'Location',
                    $e->getRouter()->assemble(
                            array(),
                            array('name' => 'zfcuser/login')
                    )
                );
                $response->setStatusCode(302);
                return $response;
            }
        },
        -100
    );
}

Но я не знаю, как мне следует расширить это, чтобы решить описанное выше действие.

Мы очень ценим любую помощь.

ОБНОВЛЕНИЕ

Мой маршрут:

'blog' => array(
            'type' => 'Segment',
            'options' => array(
                    'route'    => '/blog/:id',
                    'constraints' => array (
                            'id' => '[0-9]+'
                    ),
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action'     => 'view',
                    ),
            ),
        ),

Это моя конфигурация Zfcuser:

return array(
'zfcuser' => array(
    'password_cost' => 4,
    'login_after_registration' => true,
    'use_redirect_parameter_if_present' => true,
    'enable_display_name' => true
 )

);

После вашего обновленного кода я вижу, что он должен быть обработан, вот что происходит с URL:

http://localhost:10088/BlogProject/user/login?redirect=/BlogProject/blog/1

Но когда я пытаюсь войти в систему, я получаю эту ошибку:

Route with name "" not found

ОБНОВЛЕНИЕ 2

Zend\Mvc\Router\Exception\RuntimeException
File:
/usr/local/zend/var/apps/http/__default__/0/ProjectManager/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/TreeRouteStack.php:317
Message:
Route with name "" not found

Stack trace:
#0   /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Url.php(99): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)
#1 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Redirect.php(48): Zend\Mvc\Controller\Plugin\Url->fromRoute('/BlogProject...', Array, Array, false)
#2 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zf-commons/zfc-user/src/ZfcUser/Controller/UserController.php(158): Zend\Mvc\Controller\Plugin\Redirect->toRoute('/BlogProject...')
#3 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): ZfcUser\Controller\UserController->authenticateAction()
#4 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#5 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#6 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#7 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Forward.php(138): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#9 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zf-commons/zfc-user/src/ZfcUser/Controller/UserController.php(106): Zend\Mvc\Controller\Plugin\Forward->dispatch('zfcuser', Array)
#10 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): ZfcUser\Controller\UserController->loginAction()
#11 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#12 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#13 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#16 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#17 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#18 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#19 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(313): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#20 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/public/index.php(12): Zend\Mvc\Application->run()
#21 {main}

Это моя точка зрения.:

public function viewAction()
{
    $flashMsg = $this->flashMessenger();
    if($flashMsg->hasMessages()){
        $variables['success'] = $flashMsg->getMessages()[0];
        $flashMsg->clearMessages();
    }
    $variables['blogs'] = $this->mapper->getAllMyBlogs($this->zfcUserAuthentication()->getIdentity()->getId());
    $variables['contributedBlogs'] = $this->mapper->getAllMyContributedBlogs($this->zfcUserAuthentication()->getIdentity()->getId());
    $variables['activeBlog'] = $this->getEvent()->getRouteMatch()->getParam('id');
    $this->vm->setVariables($variables);
    $this->vm->setTemplate('application/index/index.phtml');
    return $this->vm;
}

решение

Я нашел решение:

if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
        return $this->redirect()->toRoute($redirect);
    }

Этот должен быть изменен:

if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
        return $this->redirect()->toUrl($redirect);
    }

И ваш код будет работать совершенно нормально.Вы можете найти это в строке 157 UserController.

Это было полезно?

Решение

Вы можете воспользоваться преимуществами use_redirect_parameter_if_present вариант, реализованный в ZfcUser.Если для него установлено значение true (что по умолчанию), и вы добавляете redirect параметр для маршрута входа в систему, он автоматически перенаправит вас на этот маршрут, как только вы войдете в систему.Вашей функцией могло бы быть:

$eventManager->attach( MvcEvent::EVENT_ROUTE, function( $e ) use ( $serviceManager ) {
    $routeMatch = $e->getRouteMatch();

    $auth = $serviceManager->get('zfcuser_auth_service');
    if (!$auth->hasIdentity() && $routeMatch->getMatchedRouteName() != 'user/login'
            && $routeMatch->getMatchedRouteName() != 'zfcuser/login') {
            //GENERATE THE URL FROM CURRENT ROUTE (YOUR blog ONE)
            $redirect = $e->getRouter()->assemble(
                $routeMatch->getParams(),
                array(
                    'name' => $routeMatch->getMatchedRouteName(),
                )
            );

            $response = $e->getResponse();
            $response->getHeaders()->addHeaderLine(
                'Location',
                $e->getRouter()->assemble(
                    array(),
                    array(
                        'name' => 'zfcuser/login',
                        'query' => array( 'redirect' => $redirect )
                    )
                )
            );
            $response->setStatusCode(302);
            return $response;
        }

    } ); 

Другие советы

Хотя, хотя, кажется, долго, я смог исправить это, просто заменив класс RedirectCallback.У него были проблемы с двумя из этих функций

private function routeExists($route)
{
    try {
        $this->router->assemble(array(), array('name' => $route));
    } catch (Exception\RuntimeException $e) {
        return false;
    }
    return true;
}


protected function getRedirect($currentRoute, $redirect = false)
{
    $useRedirect = $this->options->getUseRedirectParameterIfPresent();
    $routeExists = ($redirect && $this->routeExists($redirect));
    if (!$useRedirect || !$routeExists) {
        $redirect = false;
    }

    switch ($currentRoute) {
        case 'zfcuser/register':
        case 'zfcuser/login':
        case 'zfcuser/authenticate':
            $route = ($redirect) ?: $this->options->getLoginRedirectRoute();
            return $this->router->assemble(array(), array('name' => $route));
            break;
        case 'zfcuser/logout':
            $route = ($redirect) ?: $this->options->getLogoutRedirectRoute();
            return $this->router->assemble(array(), array('name' => $route));
            break;
        default:
            return $this->router->assemble(array(), array('name' => 'zfcuser'));
    }
}
.

См. Здесь для решенного кода

Это должно быть

private function routeExists($route)
{
    // first check if such rout/name exists
    // will throw exception if does not exist
    $namedRouteMatch=0;
    $urlRouteMatch=0;
    try{
         $this->router->assemble(array(), array('name' => $route));
     }catch (Exception\RuntimeException $e) {
        // didnt' match with any route name
        $match=0;
    }

    // now try to match url with routes
    try {
        $request=$this->application->getRequest();
        $request->setUri($route);
        $matchedRoute = $this->router->match($request);
        if($matchedRoute){
            $urlRouteMatch=1;
        }
    } catch (Exception\RuntimeException $e) {
        $urlRouteMatch=0;
    }
    // check if anyof them matched
   if($namedRouteMatch || $urlRouteMatch){
    return true;
   }
}

 protected function getRedirect($currentRoute, $redirect = false)
{

    $useRedirect = $this->options->getUseRedirectParameterIfPresent();
    $routeExists = ($redirect && $this->routeExists($redirect));
    if (!$useRedirect || !$routeExists) {
        $redirect = false;
    }


    switch ($currentRoute) {
        case 'zfcuser/register':
        case 'zfcuser/login':
        case 'zfcuser/authenticate':
            if($redirect){
                return $redirect;
            }
            $route =$this->options->getLoginRedirectRoute();
            return $this->router->assemble(array(), array('name' => $route));
            break;
        case 'zfcuser/logout':
            $route = ($redirect) ?: $this->options->getLogoutRedirectRoute();
            return $this->router->assemble(array(), array('name' => $route));
            break;
        default:
            return $this->router->assemble(array(), array('name' => 'zfcuser'));
    }
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top