Я реализую решение Symfony2 в соответствии с заданной спецификацией. В спецификации указано, что форма входа в систему в GET / login должна обновляться до POST / login.

Кто-нибудь знает, как изменить URL-адрес для / login_check? Могу ли я создать маршрут, который напрямую вызывает контроллер безопасности, вот так? Я не вижу ни одного контроллера в пакете безопасности.

oft_auth_login:
    pattern: /login
    defaults: { _controller: MagicSecurityBundle:Default:login_check }
    methods: [POST]

Согласно документации на security.yml,

check_path (тип: строка, по умолчанию: / login_check) Это маршрут или путь, по которому ваша форма входа должна отправить. Брандмауэр будет перехватывать любые запросы (по умолчанию только POST-запросы) к этому URL-адресу и обрабатывать отправленные учетные данные для входа.

Поэтому мне нужно создать действительный маршрут, но я не могу понять, куда он должен указывать (действие брандмауэра? Действие безопасности?) Или что он должен делать.

Я изменил его на POST / login, но он сказал, что не может его найти ...

Редактировать 30 мая:

Теперь у меня есть security.yml, который выглядит так:

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    login:
        pattern:  ^/login$
        security: false

    secured_area:
        pattern:    ^/
        anonymous: ~
        form_login:
            login_path: oft_auth_login
            check_path: oft_auth_login_check
            username_parameter: user
            password_parameter: passwd 

И routing.yml, который выглядит так:

oft_auth_login:
    pattern: /login
    defaults: { _controller: OftAuthBundle:Default:login }
    methods: [GET]

oft_auth_login_check:
    pattern: /login
    methods: [POST]

Я могу загрузить форму нормально (GET / login), а метод формы - POST, а действие - / login, но когда я отправляю его, я получаю следующую ошибку (404, маршрут не найден)

Невозможно найти контроллер по пути "/ login". Может быть, вы забыли добавить соответствующий маршрут в конфигурацию маршрутизации? 404 не найден - NotFoundHttpException

Кто-нибудь знает, какие методы кода / брандмауэра / все, что мне пришлось бы вызвать для аутентификации пользователя в пользовательском методе check_login, или любым другим способом выполнить то, что я пытаюсь сделать, а именно получить доступ и опубликовать форму входа в тот же URL (/ логин).

Заранее спасибо, Сэм

5
Nostradamnit 28 Май 2014 в 18:04

2 ответа

Лучший ответ

В вашем security.yml вы должны увидеть что-то вроде:

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    login:
        pattern:  ^/login$
        security: false

    main:
        pattern:    ^/
        form_login:
            check_path: /login_check
            login_path: /login
            always_use_default_target_path: true
            default_target_path: /secured

В вашем routing.yml вы должны увидеть что-то вроде:

## Security Routes
default:
    pattern:   /
    defaults:  { _controller: SecurityBundle:Security:login }

login:
    pattern:   /login
    defaults:  { _controller: SecurityBundle:Security:login }

login_check:
    pattern:   /login_check

logout:
    pattern: /logout

Измените check_path: /login_check в security.yml на check_path: /new_login_check

Измените pattern: /login_check в routing.yml на pattern: /new_login_check

Это изменит URL-адрес для маршрута проверки входа в систему.

Ваша форма входа, вероятно, выглядит так:

<form action="{{ path('login_check') }}" method="post" class="form-horizontal">

Фрагмент веточки {{ path('login_check') }} выводит URL-адрес маршрута, идентифицированного login_check. Это не то же самое, что URL. Пример конфигурации маршрутизации (с использованием yml):

route_identifier:
    pattern: /relative/url/path
    defaults: {_controller: ExampleBundle:Example:test}

Использование функции path ('route_identifier') направит на URL / относительный / url / путь, который вызывает метод testAction в классе ExampleController в ExampleBundle.

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

Редактировать:

Несколько ортогонально изменению маршрута проверки входа в систему, но, перечитывая ваш вопрос, он говорит, что вы хотите использовать путь / login для различных действий в зависимости от GET / POST. Это требует дополнительного шага, так как Symfony выберет первый подходящий маршрут, доступный для использования.

После выполнения вышеизложенного ваш routing.yml может содержать что-то вроде:

## Security Routes
default:
    pattern:   /
    defaults:  { _controller: SecurityBundle:Security:login }

login:
    pattern:   /login
    defaults:  { _controller: SecurityBundle:Security:login }

login_check:
    pattern:   /login

logout:
    pattern: /logout

Таким образом, он всегда будет соответствовать только маршруту входа в систему, а не маршруту login_check. Вам также необходимо указать метод:

## Security Routes
default:
    pattern:   /
    defaults:  { _controller: SecurityBundle:Security:login }

login:
    pattern:   /login
    defaults:  { _controller: SecurityBundle:Security:login }
    methods:   [GET]

login_check:
    pattern:   /login
    methods:   [POST]

logout:
    pattern: /logout

Дополнительную информацию см. В документации Symfony по маршрутизации.

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

Из документации Symfony:

Затем убедитесь, что ваш URL-адрес check_path (например, / login_check) находится за брандмауэром, который вы используете для входа в форму (в этом примере единый брандмауэр соответствует всем URL-адресам, включая / login_check). Если / login_check не соответствует ни одному брандмауэру, вы получите исключение «Невозможно найти контроллер для пути / login_check».

Это немного сложно при использовании одного и того же URL-адреса для обоих действий, но возможно. Самым большим препятствием является то, что вы не можете сопоставить брандмауэры по методу http. Первое, что вам нужно сделать, это убедиться, что оба маршрута входа соответствуют только вашему основному брандмауэру, удалив все брандмауэры, которые специально соответствуют маршрутам входа.

В приведенном выше примере это означает удаление этого раздела из security.yml:

    login:
        pattern:  ^/login$
        security: false

Это будет соответствовать первому требованию login_check, совпадающему с используемым вами брандмауэром, но неаутентифицированные пользователи больше не смогут получить доступ к маршруту входа! Это вызывает цикл перенаправления. К счастью, есть способ обойти это. В вашем файле security.yml под разделом firewalls вы должны увидеть раздел под названием access_control. (Если нет, сделайте один.) Вам нужно будет добавить следующую строку в верх этого раздела. (Опять же, сопоставление Symfony консервативно, прекращает работу, как только находит первое совпадение.)

access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }

Это явно позволит анонимным пользователям получать доступ к пути / login, но только через GET.

1
Kal Zekdor 30 Май 2014 в 14:14

Вот моя конфигурация для использования маршрута / входа в систему только с Symfony 3.1:

Security.yml:

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    login:
        pattern:  ^/login$
        security: false
        methods: [GET]

    main:
        pattern:    ^/
        form_login:
            login_path: login #this use the route name and not the pattern
            check_path: login_check # same here : route name
        logout:
            path: logout

access_control:
    - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }
    - { path: ^/, roles: ROLE_USER}

Routing.yml:

login_check:
    path: /login
    methods: [POST]
logout:
    path: /logout

Контроллер:

/**
 * @Route("/login", name="login")
 * @Method({"GET"})
 */
public function loginAction(Request $request)
{

И это работает для меня:

  • / войти с GET дать мне контроллер.
  • / войдите в систему с помощью POST, чтобы отправить форму.

Надеюсь, это кому-то поможет.

0
Guillaume S 4 Окт 2016 в 09:10