2013-03-07 16 views
14

Używam Symfony2.0 i FOSUserBundle i chciałbym wyłączyć token csrf w moim formularzu logowania.Wyłączyć token CSRF na formularzu logowania

mam wyłączone ochronę CSRF globalnie na mojej stronie w moim config.yml:

framework: 
    csrf_protection: 
     enabled:  false 

To działa dobrze, nie ma pola csrf dodany do moich postaciach. Nie dotyczy to jednak formularza logowania. Tylko na tym formularzu, otrzymuję komunikat „Nieprawidłowa CSRF Reklamowe” błąd, jeśli nie zawierają token w postaci z:

<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" /> 

Jak mogę wyłączyć token CSRF w formularzu logowania?

+1

Dlaczego chcesz to zrobić? – j0k

+0

Ponieważ mój klient chce, aby formularz logowania był sprawdzany bez względu na to, jak długo użytkownik siedział na stronie logowania. Poza tym osobiście nie uważam, że ochrona CSRF jest konieczna dla tej konkretnej witryny. –

Odpowiedz

15

Jeśli po prostu przejść do pliku security.yml i wyjąć csrf_provider z dyrektywy form_login, nie trzeba aktualizować akcję klasa lub cokolwiek.

+0

W porządku, to powinna być zaakceptowana odpowiedź .. –

27

można wyłączyć ochronę CSRF w swojej klasie formy przez ustawienie 'csrf_protection' => false w swojej tablicy opcje:

class LoginType extends AbstractType 
{ 
    // ... 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class'  => 'Acme\UserBundle\Entity\User', 
      'csrf_protection' => false 
     ); 
    } 

    // ... 

} 

W przypadku korzystania FormBuilder stworzyć swoją postać zamiast klasy AbstractType, można przekazać tablicę opcji jako drugi parametr createFormBuilder() jak ten:

$form = $this->createFormBuilder($users, array('csrf_protection' => false)) 
     ->add(...) 
     ->getForm(); 
+0

Problem polega na tym, że nie mam takiej klasy LoginType. Czy powinienem rozszerzyć klasę Symfony2 LoginType, aby ustawić właściwość csrf_protection na wartość false? Czy nie ma prostszego sposobu? –

+0

Zaktualizowałem swoją odpowiedź. Mam nadzieję, że to pomoże. –

+0

Tak, pomógł mi uświadomić sobie, że musiałem zajrzeć do SecurityController FOSUserBundle, aby ustawić csrf na false. Opublikowalam jednak wlasna odpowiedz z dalszymi szczegółami, jak postepować. +1 –

0

musiałem override FOSUserBundle's SecurityController loginAction gdzie forma logowania instanciated.

Wymieniłem:

$csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate'); 

return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => $csrfToken, 
    )); 

z:

return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => false, 
    )); 
1

jeśli używasz FOSUserBundle i chcesz wyłączyć ochronę CSRF tylko w formularzu logowania, musisz wykonać kilka kroków.

Krok 1) Stwórz swój własny pakiet obsługi & Kontroler zabezpieczeń plików

Aby nadmiernie jeździć SecurityController który jest wbudowany w FOSUserBundle, trzeba najpierw stworzyć własny pakiet użytkownika.

Tak, utwórz plik o nazwie app/src/{YourApp} /UserBundle/Controller/SecurityController.php Należy rozszerzyć oryginalnej klasy SecurityController i skopiować metody loginAction

use FOS\UserBundle\Controller\SecurityController as SecurityControllerOrig; 
class SecurityController extends SecurityControllerOrig 
{ 
    public function loginAction(Request $request) 
    { 
    } 
} 

W loginAction Sposób, skomentuj lub usunąć te linie:

$csrfToken = $this->container->has('form.csrf_provider') 
     ? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate') 
     : null; 

Następnie upewnij się, że nic nie jest przekazywana do wyświetlenia dla token CSRF:

return $this->renderLogin(array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => false, 
    )); 

Krok 2) Wyłącz CSRF sprawdzanie firewall symfony (security.yml)

Upewnij wykomentuj istniejący "csrf_provider:" linię bezpieczeństwa.yml:

firewalls: 
     main: 
      pattern: ^/ 
      form_login: 
       provider: fos_userbundle 
       #csrf_provider: form.csrf_provider 

Krok 3) Przestawianie routing dla kontrolera bezpieczeństwa FOSUserBundle za (routing.yml)

W routing.yml, skomentuj te linie:

fos_user_security: 
    resource: "@FOSUserBundle/Resources/config/routing/security.xml" 
    options: 
     expose: true 

Dodaj te wiersze poniżej Skomentowane linie:

#Over-ride the SecurityController of the FOSUserBundle: 
fos_user_security_login: 
    path: /login 
    defaults: { _controller: YourAppUserBundle:Security:login } 
    methods: [GET] 
    options: 
    expose: true 

fos_user_security_check: 
    path: /login_check 
    defaults: { _controller: FOSUserBundle:Security:check } 
    methods: [POST] 
    options: 
    expose: true 

fos_user_security_logout: 
    path: /logout 
    defaults: { _controller: FOSUserBundle:Security:logout } 
    methods: [GET] 
    options: 
    expose: true 

Uwaga 1: Poprosiłem tylko o użycie metody loginAction z Twój niestandardowy SecurityController. Pozostałe dwie metody przechodzą do klasy nadrzędnej (nie wiem, czy to robi różnicę).

Uwaga 2: Potrzebujesz części "expose: true"! W przeciwnym razie dostaniesz błąd JavaScript z pakietu routingu fos js.

To powinno wystarczyć!