2011-08-17 8 views
9

Mam operację, która pobiera dane POST zabezpieczone przez sfGuard. Oznacza to, że jeśli użytkownik nie jest zalogowany, dane POST zostaną wysłane do formularza logowania. Zazwyczaj nie stanowi to problemu, użytkownik nadal loguje się i musi ponownie przesłać dane.Wysyłanie żądania POST do zabezpieczonej akcji

Niestety, formularz logowania wydaje się używać danych POST, jak gdyby został złożony w samym formularzu. Oznacza to, że narzeka, że ​​brakuje wymaganych pól nazwy użytkownika i hasła, i narzeka, że ​​brakuje tokenu CSRF. Ten ostatni problem nie znika, po przesłaniu formularza, co oznacza, że ​​użytkownik nie może się zalogować.

Użytkownik nie powinien otrzymać formularza, jeśli nie jest zalogowany, ale użytkownik może się wylogować, ponieważ formularz jest nadal otwarty. Dlatego proszę o zachowanie szczelności interfejsu i bezbłędności.

Czy to jest wada sfGuarda, czy można tego uniknąć, czy też robię coś złego?

Aby wyjaśnić, trasa wygląda następująco:

add_subgroup: 
    url:  /group/:id/add 
    class: sfPropelRoute 
    options: 
    model: Group 
    type: object 
    param: { module: subgroups, action: create } 
    requirements: 
    group_id: \d+ 
    sf_method: [post] 

Formularz wykorzystany do złożenia wniosku jest następująca:

<form action="<?php echo url_for('add_subgroup', $group) ?>" method="post"> 
    <input type="hidden" name="group_id" value="<?php echo $group->getId() ?>" /> 
    <input type="text" name="subgroup_id" /> 
    <input type="submit" class="button" value="Add" /> 
</form> 
+0

można być bardziej szczegółowe starasz się zrobić formularz logowania, czy co? – Henry

+0

Próbuję wywołać zabezpieczoną akcję. Jeśli użytkownik nie jest zalogowany, przechodzi do istniejącego formularza logowania. Ponieważ akcja wymaga danych POST, dane POST zakłócają formę. Czy możesz dokładniej określić, o czym powinienem się bardziej szczegółowo zastanowić? – Druckles

+0

Jak sobie radzisz, jeśli użytkownik nie jest zalogowany? Jeśli wydasz przekierowanie nagłówka, dane POST powinny zostać wyczyszczone. jeśli zamiast tego włączysz to, dane POST będą obecne. –

Odpowiedz

6

Jest to wada sfGuard, ponieważ akcja logowania sprawdzi żądanie POST, a jeśli tak, powiąż formularz.

Z kodu w BasesfGuardActions.class.php:

if ($request->isMethod('post')) 
{ 
    $this->form->bind($request->getParameter('signin')); 

Osobiście nie jestem wielkim fanem spedycji pomiędzy działaniami w Symfony, i tak jak w tym przypadku, myślę, że to bardziej właściwe, aby przekierować niż naprzód. To również rozwiązuje twój problem, ponieważ spowoduje to nowe żądanie GET. Możesz osiągnąć to zachowanie, rozszerzając sfGuardBasicSecurityFilter.

class mySecurityFilter extends sfGuardBasicSecurityFilter 
{ 

    protected function forwardToLoginAction() 
    { 
    $context = $this->getContext(); 
    // If you want to redirect back to the original URI (note: original POST data will be lost) 
    $context->getUser()->setReferer($context->getRequest()->getUri()); 
    $url = sfConfig::get('sf_login_module') . '/' . sfConfig::get('sf_login_action'); 
    $context->getController()->redirect($url); 
    throw new sfStopException(); 
    } 

} 

Teraz w app/myapp/config/filters.yml

security: 
    class: mySecurityFilter 
0

Jest to prawdopodobnie dlatego, że umieścić kod z auth login dane w tej samej akcji (prawdopodobnie przez sprawdzenie, czy żądanie jest wysyłane).

Jednak można podzielić tę akcję na dwie akcje. Jeden do wyświetlania formularza logowania, a drugi do autoryzacji danych logowania użytkownika. I ustaw swój bezpieczny stan na działanie, które ma tylko pokazać formularz logowania.