How I fixed exception ‘Bad credentials’ with FOSUserBundle

Waaaa, no fair, unexpected nasty bug message on prod? Boo.

Yup, this one just caught me out – and thankfully my good buddy, brother, and friend managed to pick it up whilst doing some ad-hoc Quality Assurance checks.

Disclaimer: This site may have been in prod, but only just, this was the first release to live 🙂 So no major foul.

Disclaimer part 2: Yes, there is now a passing Codeception acceptance test to make sure this never happens again 🙂

Ok, so this is the bug message (mainly for Google users benefit):

UPDATE `your_table_name` SET exception 'Symfony\Component\Security\Core\Exception\BadCredentialsException' with message 'Bad credentials' in /var/www/html/mysite.dev/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:73
 Stack trace: #0 /var/www/html/mysite.dev/app/cache/prod/classes.php(120): session_start() #1 /var/www/html/mysite.dev/app/cache/prod/classes.php(198): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() #2 /var/www/html/mysite.dev/app/cache/prod/classes.php(498): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->getBag('attributes') #3 /var/www/html/mysite.dev/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ContextListener.php(76): Symfony\Component\HttpFoundation\Session\Session->get('_security_main') #4 /var/www/html/mysite.dev/app/cache/prod/classes.php(2463): Symfony\Component\Security\Http\Firewall\ContextListener->handle(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) #5 [internal function]: Symfony\Component\Security\Http\Firewall->onKernelRequest(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) #6 /var/www/html/mysite.dev/app/cache/prod/classes.php(1750): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) #7 /var/www/html/mysite.dev/app/cache/prod/classes.php(1683): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) #8 /var/www/html/mysite.dev/app/cache/prod/classes.php(1847): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) #9 /var/www/html/mysite.dev/app/bootstrap.php.cache(2965): Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) #10 /var/www/html/mysite.dev/app/bootstrap.php.cache(2938): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #11 /var/www/html/mysite.dev/app/bootstrap.php.cache(3087): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #12 /var/www/html/mysite.dev/app/bootstrap.php.cache(2337): Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #13 /var/www/html/mysite.dev/web/app.php(27): Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #14 {main}

Lovely job.

Anyway, this was a pretty simple fix, even though there isn’t much about this on Google.

As part of this project, I needed to overwrite the default FOS User Bundle templates with my own. A pretty typical task tbh.

As it happened though, I had removed kept the FOS User Bundle error logic, but removed the translation part.

Something like this:

 {% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %} {% if error %}
{{ error.messageKey|trans(error.messageData, 'security') }}
{% endif %}

And I had gone ahead and changed that in my template to something like this:

 {% block content %} {% if error %}
{{ error.messageKey|trans(error.messageData, 'security') }}
{% endif %} {% endblock %}

So I had removed the trans_default_domain, which in turn, was – as far as I can tell – then simply rendering out the full stack trace.

I’m not sure if FOSUserBundle catches that error, and then translates it? That seems kinda unusual to me.

Anyway, hopefully this saves someone some time, someday, some time soon 😉

How to Fix Composer: ErrorException fork failed – cannot allocate memory

If you’re trying to deploy a Symfony project – or Laravel, or pretty much anything using composer – and your deployment server is a little anemic on the memory side of things (Amazon AWS, tiny Digital Ocean droplets, even the basic Linode offerings), then you may well hit an issue when you run composer update during your deploy.

There’s quite a long github issue thread about it, and another one on Stack Overflow.

Anyway, after much frustration, here is my fix – which works for me, hopefully it will work for you too.

This assumes you are developing locally and then deploying to prod using git, which I highly advise. But it will work for any type of deploy if you follow the steps and tweak accordingly.

  1. Do a composer update on your dev box
  2. Commit the updated composer.lock file
  3. Push the commit with the lock file to your prod server (or wherever you’re getting that error)
  4. From the prod server (or wherever), delete your composer cache (rm -rf ~/.composer)
  5. From the prod server (or wherever), delete your vendor folder (rm -rf vendor)
  6. From the prod server (or wherever), run composer install

So, whilst the above is the high level overview, here’s how I did it irl.

  1. Using ssh, I connected to my development virtual machine (VMWare), where from the Symfony root dir (/var/www/html/myproject.dev/), I ran composer update
  2. Wait a while, whilst number 1 finishes.
  3. From my local machine, download the newly updated composer.lock file. Git sees this as a changed file, and so I can then do a git commit on the updated composer.lock file
  4. As I have already set up a git remote for my production server, I can then do a git push for the commit with the lock file to my production server.
  5. When the commit hits the server, the post-receive hook is run automatically, which does all the Symfony deploy stuff like clearing the cache, dumping assets, reinstalling vendors etc.
  6. If all this sounds great, but deploying with Git is something you’re unsure of, I highly recommend this Digital Ocean article, which makes it very easy.

    Hope it helps!