Symfony2 Firewall: перенаправление на регистрационную форму вместо входа в систему

Я работаю над простым магазином (для компиляции предложений) на основе Symfony2.

После добавления предметов в корзину, пользователь может перейти к сводке своего предложения, а затем запросить скомпилированное предложение.

Страница сводки защищена следующим брандмауэром:

security:
firewalls:
 secured_area:
 pattern: ^/
 anonymous: ~
 provider: default
 form_login:
 login_path: acme_security_login_route
 check_path: acme_security_login_check_route
 csrf_provider: form.csrf_provider
 logout: ~

 default:
 anonymous: ~

access_control:
 - { path: ^/request-offer, roles: ROLE_CLIENT }

providers:
 default:
 entity: { class: AcmeShopBundle:User }

encoders:
 Symfony\Component\Security\Core\User\User: plaintext
 Acme\ShopBundle\Entity\User:
 algorithm: bcrypt
 cost: 15

Это означает, что если клиент вошел в систему, он будет напрямую получать сводку, а если нет, он перенаправляется на страницу входа.

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

Параметры, описанные в ReferenceBundle Configuration Reference, не позволяют этого. Конечно, изменение пути login_path также не является решением.

Что было бы самым лучшим решением для этого?

2 ответа

Ответ Nextar привел меня к решению.

Цитируя этот вопрос:

служба, указанная access_denied_handler, вызывается только в том случае, если у пользователя есть недопустимые привилегии для доступа к ресурсу. Если пользователь не аутентифицирован вообще, access_dened_handler никогда не вызывается. Предоставление услуги entry_point в security.yml действительно помогло решить проблему

Поэтому я закончил с этим:

#services.yml
acme.security.entry_point.class: ArtCube\ShopBundle\Service\EntryPointHandler

services:
 acme.security.entry_point_handler:
 class: %acme.security.entry_point.class%
 arguments:
 router: @router

Затем я добавил эту службу в свой security.yml, сразу после logout: ~ line (см. начальный вопрос):

entry_point: art_cube_shop.security.entry_point_handler

И создал сервис:

// Acme/ShopBundle/Service/EntryPointHandler.php

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;

class EntryPointHandler implements AuthenticationEntryPointInterface {

 protected $router;

 public function __construct(Router $router)
 {
 $this->router = $router;
 }

 public function start(Request $request, AuthenticationException $authException = null)
 {
 if($authException instanceof InsufficientAuthenticationException)
 {
 return new RedirectResponse($this->router->generate('acme_security_registration_route'));
 } 
 else
 {
 return new RedirectResponse($this->router->generate('acme_security_login_route'));
 }
 }
}


На мой взгляд, хорошим решением является добавление собственного AccessDeniedExceptionHandler, как это можно объяснить здесь.

Использование SymDony2 AccessDeniedHandlerInterface

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

http://symfony.com/doc/current/components/config/definition.html

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

licensed under cc by-sa 3.0 with attribution.