Basic Prototype App with Symfony3

The objective of this is to build a simple route, and controller that handles this entire “application.”

The components of this simple prototype are essentially a bunch of HTML pages with interaction hard-coded or baked into the twig templates. So the objective here is to build the structure such that building a new template is all that is required and the application will then pick it up.


  1. Separately a custom controller handles exception catching and 404 errors.
  2. Everything, including authentication/authorization can be “faked”
    1. Presumably you’d hide this behind HTTP-Basic or keep local only.

The Route

The Controller

How it Works

Now all you need to do is build your filenames to match and you can create template files that work out of the box.

Now your routes map to filenames, which for the purposes of a simple static HTML prototype makes things very easy for any designer or developer to add and work with:

Route (path) Template filename
/jake/home DemoBundle\Resources\views\Jake\home.html.twig
/auth/forgot-password DemoBundle\Resources\views\Auth\forgot-password.html.twig
/jake/dashboard DemoBundle\Resources\views\Jake\dashboard.html.twig

Improve Symfony3 cache/logs performance by environment

Tired of the permission errors with your cache/logs in a Vagrant environment? Me too!

After being mildly annoyed with having to manually delete /var/cache and /var/logs repeatedly during “local” development, I decided to brut force matters into my own hands and solve this little annoyance once and for all. Ironically, Symfony 3.3 is addressing some of this, so it may be obsolete by then, but in the meantime…

What are we doing here?

  1. Define cache and logs directories for a specific environment.
    1. Wouldn’t it be awesome if we could customize these as parameters in the FrameworkBundle? Yes, yes it would!
  2. Write a simple CacheCommand that overrides the default cache:clear
  3. PARTY!!!!

Customize your getCacheDir and getLogDir methods by your environment

In my case, I typically use Vagrant/Virtualbox for local development, and Docker containers/bitbucket-pipelines for “test” while Production is a variety/flavor of AWS EC2 instances which have some additional flare.

Write a CacheCommand you can love and cherish forever and ever


Now you can enjoy life and all references to cache:clear will run your new and improved command that will also work noticably faster in Vagrant development environments; thanks entirely to Benjamin Eberlei and his wonderful blog post.


cd /path/to/myapp && php bin/console cache:clear

Symfony3: JWT Authentication w/ Login Attempt Limits

One of my current projects is using JWT Authentication for an API built on Symfony (shocker, I know). One of the things I wanted to build into this was a limiter on the number of “login” attempts for the API that would lock someone out for x minutes after n failed attempts; mirroring typical traditional form login behavior.

This was accomplished with the following components:

  • Separate non-entity-driven database table
  • Parameters for defining the number of minutes to lock and the number of attempts before triggering a a lock.
  • A simple handler to check our table and do some simple maintenance and querying.

Separate non-entity-driven database table

The database table to track login attempts needed to be separate from a Doctrine (the ORM in this case) entity because a failed attempt naturally did not map to a real User. Similarly, we didn’t want to track ip_addr of logged in users because we are not Vizio. So, that being said, we created a very simple database table to track login attempts by ip_addr:


Again in this case, we wanted to parameterize the values we used to determine the number of attempts, and the number of minutes a user was locked out from attempting to login. With Symfony this is a simple addition to the parameters file.

It’s important to note that timezone is very important here for comparing dates (later), so make sure when you define this (or if you ever change it) that you clear out the login_attempts table as well.


Most importantly, we had to build a simple handler to manage our queries and maintenance actions. Ultimately, this is where the magic happens but the most important part is still last where we handle the actual logic in our Authentication controller (see below). However, this handler does the heavy lifting, and does have some room for improvement, particularly with Unit Testing.

Define LoginAttemptHandler as a Service

Symfony needs to understand this handler is a service, so we can use it in our Controller (next).

Handle Login Attempts in our Authentication Controller

Now, every time there is a JWT Token request, we have a slight amount of extra overhead to verify login attempts in our Controller.