2
votes

I'm new to Silex, I used this tutorial to set up Doctrine ORM.

But now when I'm trying to log in, i got "Bad credentials" error. It happens when I use the default "login_check" controller.

If I use a custom one, it works but I don't know how to redirect the user to the page he was looking for. (I tried whith $request->headers->get('referer') in my login controller but it's empty.)

Here's my custom login_check contorller :

$app->post('/login-check-perso', function(Request $request) use ($app){

$route    = $request->request->filter('route');
$password = $request->get('_password');
$username = $request->get('_email');


$userProvider = new \Lib\Provider\UserProvider($app);

$user = null;
try {
    $user = $userProvider->loadUserByUsername($username);
} 
catch (UsernameNotFoundException $e)
{
}

$encoder = $app['security.encoder_factory']->getEncoder($user);

// compute the encoded password
$encodedPassword = $encoder->encodePassword($password, $user->getSalt());

// compare passwords
if ($user->getPassword() == $encodedPassword)
{
    // set security token into security
    $token = new UsernamePasswordToken($user, $password, 'yourProviderKeyHere', array('ROLE_ADMIN'));
    $app['security']->setToken($token);

    // redirect or give response here
} else {
    // error feedback
    echo "wrong password";
    die();
}
// replace url by the one the user requested while he wasn't logged in
return $app->redirect('/web/index_dev.php/admin/');
})->bind('login_check_perso');

So if someone can explain how to use the default "login_check", or explain to me how can I redirect user to the page he was trying to visit while not logged, it'll be great.

Thanks

EDIT:

I think the "Bad Credentials" is caused by a wrong encoders setting, I used this
to configure mine :

$app['security.encoder.digest'] = $app->share(function ($app) {
    // use the sha1 algorithm
    // don't base64 encode the password
    // use only 1 iteration
    return new MessageDigestPasswordEncoder('sha1', false, 1);
});

$app['security.encoder_factory'] = $app->share(function ($app) {
    return new EncoderFactory(
        array(
            'Symfony\Component\Security\Core\User\UserInterface' => $app['security.encoder.digest'],
            'Entity\User'                          => $app['security.encoder.digest'],
        )
    );
});

Is that correct ?

1

1 Answers

0
votes

You can extend the DefaultAuthenticationSuccessHandler, which will be called after a successfull login, I doing it like this:

// overwrite the default authentication success handler
$app['security.authentication.success_handler.general'] = $app->share(function () use ($app) {
  return new CustomAuthenticationSuccessHandler($app['security.http_utils'], array(), $app);
    });

Create a CustomAuthenticationSuccessHandler:

use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Silex\Application;

class CustomAuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler
{
    protected $app = null;

    /**
     * Constructor
     *
     * @param HttpUtils $httpUtils
     * @param array $options
     * @param unknown $database
     */
    public function __construct(HttpUtils $httpUtils, array $options, Application $app)
    {
        parent::__construct($httpUtils, $options);
        $this->app = $app;
    }

    /**
     * (non-PHPdoc)
     * @see \Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler::onAuthenticationSuccess()
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $user = $token->getUser();
        $data = array(
            'last_login' => date('Y-m-d H:i:s')
        );
        // save the last login of the user
        $this->app['account']->updateUser($user->getUsername(), $data);
        return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
    }
}

I'm using onAuthenticationSuccess() to save the users last loging datetime. You can use the createRedirectResponse() to redirect the user to the starting point you need.