ZfcUser перенаправляет динамический URL-адрес после входа в систему
-
20-12-2019 - |
Вопрос
Я учусь разрабатывать веб-сайт с помощью 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'));
}
}
.