1

Symfony クックブックのチュートリアル「従来のログイン フォームの作成方法」に触発されたカスタム symfony セキュリティ ログインに問題があります。/login ルートからログインするまで、すべて正常に動作します。次に、リダイレクト先のすべてのルートが無限ループを引き起こしています。多分私は何かを逃していますか?

//security.yml セキュリティ:

encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt

providers:
    mysql:
        entity:
            class: AppBundle:User
            property: username


firewalls:
    # disables authentication for assets and the profiler, adapt it according to your needs
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        anonymous: ~
        form_login:
            login_path: login
            check_path: login_check
        logout:
            path: logout


access_control:
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

//routing.yml

index:
path: /
defaults: { _controller: AppBundle:Main:main }
app:
    resource: "@AppBundle/Controller/"
    type:     annotation

//SecurityController.php

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class SecurityController extends Controller
{
/**
 * @Route("/login", name="login")
 */
public function loginAction() {
    $authenticationUtils = $this->get("security.authentication_utils");

    $error = $authenticationUtils->getLastAuthenticationError();
    $name = $authenticationUtils->getLastUsername();

    return $this->render(
        ':security:login.html.twig',
        ["name" => $name, "error" => $error]
    );
}
/**
 * @Route("/login_check", name="login_check")
 */
public function loginCheckAction() {
}
/**
 * @Route("/logout",name="logout")
 */
public function logoutAction() {
}

}

//login.twig.html

{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}

<form action="{{ path('login_check') }}" method="post">
     <label for="username">Username:</label>
     <input type="text" id="username" name="_username" value="{{ name }}" />

     <label for="password">Password:</label>
     <input type="password" id="password" name="_password" />
     <input type="hidden" name="_target_path" value="/" />

     <button type="submit">login</button>
</form>
4

5 に答える 5

3

さて、ようやく問題を特定しましたが、問題はルートやセキュリティにはまったくありませんでした。User Entity のシリアル化が間違っていました。いくつかのミススペル symfony がデバッガーで言及されていません。この種の動作を引き起こしたのは奇妙です。とにかく、私を助けようとした人に感謝します。

于 2016-03-28T18:11:29.253 に答える
0

このようにしてみてください: security.yml セキュリティ:

encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt

providers:
    mysql:
        entity:
            class: AppBundle:User
            property: username


firewalls:
    # disables authentication for assets and the profiler, adapt it according to your needs
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        anonymous: ~
        form_login:
            login_path: login
            check_path: login_check
        logout:
            path: logout


access_control:
    - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

ルーティング.yml

login:
    resource: "@AppBundle/Controller/SecurityController.php"
    type:     annotation
app:
    resource: "@AppBundle/Controller/"
    type:     annotation

SecurityController.php

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class SecurityController extends Controller
{
/**
 * @Route("/login", name="login")
 */
public function loginAction() {
    $authenticationUtils = $this->get("security.authentication_utils");

    $error = $authenticationUtils->getLastAuthenticationError();
    $name = $authenticationUtils->getLastUsername();

    return $this->render(
        ':security:login.html.twig',
        ["name" => $name, "error" => $error]
    );
}
/**
 * @Route("/login_check", name="login_check")
 */
public function loginCheckAction() {
}
/**
 * @Route("/logout",name="logout")
 */
public function logoutAction() {
}

}

login.twig.html

{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}

<form action="{{ path('login_check') }}" method="post">
     <label for="username">Username:</label>
     <input type="text" id="username" name="_username" value="{{ name }}" />

     <label for="password">Password:</label>
     <input type="password" id="password" name="_password" />
     <input type="hidden" name="_target_path" value="{{ path('THE_NAME_OF_THE_ROUTE_YOU_WANT_TO_GO') }}" />

     <button type="submit">login</button>
</form>

mainController では、注釈ルートを使用し、たとえば「THE_NAME_OF_THE_ROUTE_YOU_WANT_TO_GO」を「/ page」に置き換える必要があります...

ここでいくつかのヘルプ: http://symfony.com/doc/current/book/routing.html

于 2016-03-28T12:24:41.417 に答える
0

あなたは変わるべきです

access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }

access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }

login_check をファイアウォールの背後に配置します。

あなたの routing.yml は私には奇妙に思えます。コントローラーと小枝を投稿してルートを確認できますか?

于 2016-03-28T04:05:28.223 に答える
0

その理由は、ログイン スクリプトがログイン ページに転送しているためです。ログインしていることがわかると、リファラーに転送されます。これはログイン ページです。などなど。

これを回避するには、いくつかのオプションがあります。

app/config/security.yml1)ユーザーがログインするたびに特定のルートに転送されるように、デフォルトのターゲットパスを設定できます。このアプローチの問題点は、 を使用するとalways_use_default_target_path参照ページに移動しないことを意味しますが、それを使用せずにログインに失敗すると、ログイン ページにリダイレクトされます (この参照元点)。

firewalls:
    //..
    main:
        anonymous: ~
        form_login:
            default_target_path: **default_route**
            always_use_default_target_path: true
            login_path: login
            check_path: login_check
        logout:
            path: logout

2)デフォルトのターゲットパスを設定するフォームログインにフィールドを設定できます。これは、ケースに応じてリファラーまたは指定されたパスになります。このアプローチの問題点は、ユーザーが転送されるためにログイン プロセスを実行する必要があるため、ユーザーが何らかの理由でログイン ページに戻った場合、リダイレクトされる前に再度ログインする必要があることです。

//...

{% set referer = app.request.headers.get('referer') %}
{% set targetPath = referer is not null and referer != url('login')
    ? referer
    : path('**default_route**')
%}

<form action="{{ path('login_check') }}" method="post">
    //...

    <input type="hidden" name="_target_path" value="{{ targetPath }}" />
</form>

3)私の推奨事項ユーザーがすでにログインしているかどうかを確認し、ユーザーを特定のルートにリダイレクトできるように、ログインコントローラーにチェックを設定できます。これの利点は、すでにログインしているユーザーがログイン フォームに移動するのを停止しますが、可能な場合はユーザーを参照ページ/ルートに転送できるようにすることです。

/**
 * @Route("/login", name="login")
 */
public function loginAction() {
    if (null !== $this->getUser()) {
        return new RedirectResponse($this->generateUrl('**default_route**'));
    }

    //...
}
于 2016-03-28T10:34:48.477 に答える