Sending POST Request to Secured Action
Asked Answered
N

2

9

I have an action that takes POST data secured by sfGuard. This means that if the user is not logged in, the POST data will be sent to the log in form. Ordinarily, this is not a problem, the user continues to log in, and has to submit the data again.

Unfortunately, the log in form seems to be using the POST data as if it was submitted with the form itself. This means that it is complaining that the required username and password fields are missing, and it complains that it is missing a CSRF token. This last problem does not go away, after submitting the form, meaning the user cannot log in, anyway.

The user should not be presented with the form if not logged in, but it might be possible for the user to log out with the form still open. So I am asking in the interest of keeping the interface watertight and error-free.

Is this a shortcoming of sfGuard, can it be avoided, or am I doing something wrong altogether?

To clarify, the route looks like this:

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]

The form used to submit the request is as follows:

<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>
Northumberland answered 17/8, 2011 at 16:29 Comment(7)
can you be more specific are you trying to make a login form or what?Magnetron
I am attempting to call a secured action. If the user is not logged in, it goes to an existing login form. As the action requires POST data, this POST data is interfering with the form. Can you be more specific about what I should be more specific about?Northumberland
How are you handling if the user is not logged in? If you issue a header redirect then the POST data should be cleared. if you instead are including it, then the POST data will be present.Mimeograph
Why can the unauthenticated user see the form, when the posting requires to be authenticated?Adapter
@watcher sfGuard is handling the forward if the user is not logged in. I don't believe it is a header redirect.Northumberland
@Adapter An unauthenticated user cannot see the form. I would, however, prefer it to be watertight, and it's more a theoretical question.Northumberland
I'll give a bounty to whoever answer the question. But I can't add it right now to the question, as I have an active bounty.Maomaoism
C
6

It is a shortcoming of sfGuard, because the signin action will check for a POST request, and if so bind the form.

From the code in BasesfGuardActions.class.php:

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

I'm personally not a big fan of forwarding between actions in symfony, and just like in this case, I think it's more appropriate to redirect than forward. This also solves your problem because this will result in a new GET request. You can accomplish this behavior by extending 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();
  }

}

Now in app/myapp/config/filters.yml

security:
  class: mySecurityFilter
Call answered 31/8, 2011 at 8:3 Comment(0)
R
0

This is probably because you put the code of auth the login data in the same action (probally by check whether the request is post).

However You could divide the one action into two actions. One for showing the login form, and the another is for auth the user's login data. And set your secure_action to the action which is just to show the login form.

Rabjohn answered 31/8, 2011 at 6:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.