2016-03-27 1 views
0

Ich habe ein Problem mit benutzerdefinierten symfony Sicherheitsanmeldung inspiriert von Tutorial "Wie man ein traditionelles Login-Formular erstellen" aus Symfony Kochbuch. Alles funktioniert gut, bis ich mich von/Login Route einloggen. Dann verursacht jede Route, die ich umleiten möchte, eine unendliche Schleife. Vielleicht vermisse ich etwas?Symfony 3 Sicherheit Nach der Anmeldung gibt es eine unendliche Umleitung

//security.yml Sicherheit:

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

Antwort

0

sollten Sie ändern

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

zu

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

login_check hinter der Firewall zu haben.

Ihre routing.yml scheint mir seltsam, könnten Sie Ihren Controller und Ihren Zweig veröffentlichen, um Ihre Routen zu sehen?

+0

Bitte Update überprüfen – vnarek

0

Der Grund ist, weil das Anmeldeskript wird Sie zur Anmeldeseite weiterleiten, wenn es sieht, dass Sie in sie angemeldet sind, ist man auf die Referrer Spedition .. die der Login-Seite ist .. und so weiter ..

Um dies zu umgehen, haben Sie ein paar Optionen.

1) Sie könnten einen Standardzielpfad in Ihrem app/config/security.yml festlegen, so dass jedes Mal, wenn sich ein Benutzer anmeldet, sie an die bestimmte Route weitergeleitet werden. Das Problem mit diesem Ansatz ist, dass die Verwendung von always_use_default_target_path bedeutet, dass es nie auf die verweisende Seite gehen wird, aber wenn Sie es nicht verwenden und ein Fehler beim Login auftritt, werden Sie auf die Anmeldeseite geleitet (der Referrer bei dieser Punkt).

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) Sie können ein Feld in Ihrem Formular Login gesetzt, die einen Standardzielpfad setzt, die die Referrer oder eine spezifizierte je nach Fall sein könnte. Dieses Problem bei diesem Ansatz besteht darin, dass der Benutzer den Anmeldeprozess durchlaufen muss, um weitergeleitet zu werden. Wenn die Benutzer aus irgendeinem Grund zur Anmeldeseite zurückkehren, müssen sie sich erneut anmelden, bevor sie umgeleitet werden.

//... 

{% 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) Meine Empfehlung Sie einen Scheck in Ihrem Login-Controller einstellen könnten, dass, wenn der Benutzer bereits angemeldet ist überprüfen und dann den Benutzer auf eine bestimmte Route umgeleitet wird. Dies hat den Vorteil, dass Benutzer, die bereits eingeloggt sind, nicht mehr zum Login-Formular wechseln. Sie können jedoch weiterhin Benutzer auf die verweisende Seite/Route weiterleiten, wenn dies möglich ist.

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

    //... 
} 
+0

Immer noch nichts. Ich habe jede Empfehlung ohne Verbesserungen ausprobiert. – vnarek

0

@qooplmao Ich verstehe nicht, warum du gesagt hast „die Referrer .., die der Login-Seite ist“ die Referrer ist „/“ Hexe ist nicht die Login-Seite („/ login“), sondern eine Route irgendwo im HauptController. Wenn die/login Route vorher übereinstimmt/wird es in Ordnung sein nein?

Frühere Routen immer gewinnt, dann könnten die routing.yml

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

sind Sie könnten den Index entfernen, wenn Sie Anmerkungen in dem Haupt-Controller verwenden.

+0

Funktioniert auch nicht für mich. Der Index wird wie eine Art Hotfix verwendet, um die Standardroute festzulegen. AppBundle: Main: Haupt Annotation ist definiert als/Seite/{Slug} mit Default-Wert für Slug – vnarek

+0

Was sagen die Debug-Toolbar? – lemairep

+0

Nur zu verstehen Sie wollen Ihre Website vollständig hinter der Firewall? – lemairep

0

versuchen wie folgt aus: security.yml Sicherheit:

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

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> 

In Ihrem mainController müssen Anmerkungen Routen verwenden und zum Beispiel ‚THE_NAME_OF_THE_ROUTE_YOU_WANT_TO_GO‘ durch ‚/ Seite‘ ersetzen, wenn es die Route gehen ...

hier etwas Hilfe möchte ist: Ich so http://symfony.com/doc/current/book/routing.html

+0

Jetzt, nachdem ich meinen Laptop neu gestartet habe und mich eingeloggt habe, werde ich zu ** localhost: 8000/page ** umgeleitet, aber es ist eine leere Seite und dann gleich Problem tritt wieder auf. Infinite Seite laden auf jede Anfrage, die ich versuche. Sogar Routen, die nicht existieren, verursachen unendliches Seitenladen. – vnarek

+0

Löschen Sie den Cache nach den Änderungen? – lemairep

+0

Konnten Sie versuchen, die Brandmauer zu entfernen und Ihren Maincontoller mit/Seite zu prüfen, sieht wie ein Problem mit Ihrem Steuerpult aus ... – lemairep

1

Ok endlich Problem und das Problem war nicht in den Routen oder Sicherheit überhaupt. Ich habe gerade in User Entity falsch serialisiert. Einige falsch geschrieben Symfony nicht im Debugger erwähnt. Es ist komisch, dass es diese Art von Verhalten verursacht hat. Jedenfalls danke an jeden, der versucht hat mir zu helfen.