I am implementing a dialog for my login form in symfony2, it works well except I would want to handle the return with some more logic, now I don’t know how to do that since the firewall configuration picks up the login submission.
What happens is that if login failed, the html of my dialog is replaced with the new html returned by the login controller, this is all fine.
But if a successful login attempt occurs, the html of my login dialog is replaced with my entire site (since a successful symfony2 login will redirect to the start page…).
In flat PHP I would add this to the login controller
if (login_successful) {
return "success";
}
and in my dialog function put
if (returned_data == "success") {
refresh_page(); // or location.href('something')
}
else
{
// replace dialog_html with the returned html
}
But as I look to the action taking care of the login form submission i FOS user bundle, this is what I find
public function checkAction()
{
throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
}
So I realize this is all taken care of behind the scenes in symfony2, can I even get at this then?
Actual sample code (JS)…
function submitFormWithAjax(form) {
form = $(form);
$.ajax({
url: form.attr('action'),
data: form.serialize(),
type: (form.attr('method')),
dataType: 'html',
success: function(data) {
if (data == 'success') {
//Success-token is passed, so reload page (will close dialog and load the logged-in start screen since user is now fully authenticated
location.reload();
}
else {
//Form is returned, probably with errors, so let user try again...
$('#formDialog').html(data);
}
}
});
return false;
}
and the form…
<form action="{{ path("fos_user_security_check") }}" method="post" id="login-form">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<TABLE>
<TR>
<TD><label for="username">Login</label></TD>
<TD><input type="text" placeholder="användare" id="username" name="_username" value="{{ last_username }}" /></TD>
</TR>
<TR>
<TD><label for="password">Lösenord</label></TD>
<TD><input type="password" placeholder="lösenord" id="password" name="_password" /></TD>
</TR>
<TR>
<TD><label for="remember_me">Kom ihåg mig</label></TD>
<TD><input type="checkbox" id="remember_me" name="_remember_me" value="on" /></TD>
</TR>
<!--
<TR>
<TD></TD>
<TD align="right"><input type="submit" id="_submit" name="_submit" value="Logga in" /></TD>
</TR>
-->
</TABLE>
</form>
As per m2mdas suggestion below, I now have these set up:
config.yml
#My services
services:
my.authentication.success_handler:
class: Hemekonomi\UserBundle\AuthenticationSuccessHandler
parent: security.authentication.success_handler
my userbundle now has this class
<?php
namespace MyApp\UserBundle;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler
{
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
if(true === $request->isXmlHttpRequest()) {
return new Response("success");
}
//default redirect operation.
return parent::onAuthenticationSuccess($request, $token);
}
}
… and the security.yml has…
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
success_handler: my.authentication.success_handler
logout: true
anonymous: true
The error I get is this
RuntimeException: The parent definition "security.authentication.success_handler" defined for definition "my.authentication.success_handler" does not exist.
Could it have something to do with formatting, is it different in xml/yml? I am no expert in either so…
I ended up using this solution (thanks to m2mdas & http://blog.alterphp.com/2011/10/set-up-authenticationsuccesshandler.html)
config.yml
security.wml
successhandler (including slightly more functionality than what I asked for, might use this later on):