Login Throttling

This Chapter isn't
quite ready...

Rest assured, the gnomes are hard at work
completing this video!

Browse Tutorials

Coming soon...

Um, simply a secure system has a lot of cool stuff in it. Like remember me, cookies, impersonation voters even has built in support for eight magic link authenticator, where you email a link to your user and they click that to log in one other really cool feature is log-in throttling a way to prevent someone from a single IP address from testing passwords on your site, by trying to log in over and over and over and over again. And it's super easy to use. So under your firewall, all you need to do is enable it. So you can do that by saying log-in throttling true.

If you stop right there and refresh any page, you're going to get that air. It says, this requires the rate limiter component. Cool. Let's copy that composer require line spin or whatever terminal and Ron

composer require symfony/rate-limiter

This package has a also installed something called Symfony the lock, which has a recipe I'll run, get status to see what it did. Interesting. So create a new config packages, lock.yaml file, and also modified our dot inf. So in order to sort of keep track of, who's been trying to log in the log and throttling system needs to store that data somewhere. And it used the Symfony lock component to do that inside of our.in file at the bottom. There's a new lock and DSN, which is set to summit summit for this is basically a string. And you can see example above of storing the locks in Postgres of where to store this information. Uh, 74 is the easiest place to store stuff.

It's an easy way to keep track of things on a single machine. So if you had multiple servers, you would need to use something else like Postgres or Retis, but this will work great for our situation. And that's it. The Ray learner components going to S the logging throttling is gonna start using the, uh, lock component. The lock component will S savings at the Semafore, which otherwise we can try this for refresh. It works again. So by default, it's going to block five log in attempts from the same user. So one do three or five. Now the sixth one doesn't work and it locks you out. It also blocks, um, attempts from the same IP address and any email. If you hit 50 of those within a minute, I need to look up the specifics on that. All of this can be configured and it's documented how you can configure it. And we can even say some of the configuration options by running Symfony console, Viva config security, and seeing the default configuration under that log and thrive. So you can see max attempts at five minutes interval one minute.

So that's just a really cool thing that you get for free. I would recommend using this and also potentially using it with something like CloudFlare, which can offer you additional production. Um, but one of the most interesting things for us about this is how this works. It works via Symfony's listener system. After we log in, whether successfully or failed a number of events are dispatched through that process, and you can hook into them to do different things. So the code that runs, this is actually a listener called log-in throttling listener. You can open it and let it shift shift, logging, throttling, listener dot PHP. And here it is the specifics on this aren't too important.

You can see it's using something called a rate limiter that kind of checks thing, and ultimately throws this exception, which causes the message that we saw this check passport, uh, method check passport event. It's called every after every authentication. I need to get the words right before that. So also another listen to I called on successful log in, which is called after we successfully log in and you can see it resets the limiter. So once you are successful, it kind of clears things out. So this is really cool, and it's kind of our first vision into how the, the event system works. Let's look at an event system further next and use it to prevent our user from logging in. If their email address is not yet confirmed.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.4.1 || ^8.0.0",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^3.3", // v3.3.0
        "composer/package-versions-deprecated": "^1.11", // 1.11.99.4
        "doctrine/annotations": "^1.0", // 1.13.2
        "doctrine/doctrine-bundle": "^2.1", // 2.4.3
        "doctrine/doctrine-migrations-bundle": "^3.0", // 3.1.1
        "doctrine/orm": "^2.7", // 2.10.1
        "knplabs/knp-markdown-bundle": "^1.8", // 1.9.0
        "knplabs/knp-time-bundle": "^1.11", // v1.16.1
        "pagerfanta/doctrine-orm-adapter": "^3.3", // v3.3.0
        "pagerfanta/twig": "^3.3", // v3.3.0
        "phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
        "scheb/2fa-bundle": "^5.12", // v5.12.1
        "scheb/2fa-qr-code": "^5.12", // v5.12.1
        "scheb/2fa-totp": "^5.12", // v5.12.1
        "sensio/framework-extra-bundle": "^6.0", // v6.2.0
        "stof/doctrine-extensions-bundle": "^1.4", // v1.6.0
        "symfony/asset": "5.3.*", // v5.3.4
        "symfony/console": "5.3.*", // v5.3.7
        "symfony/dotenv": "5.3.*", // v5.3.8
        "symfony/flex": "^1.3.1", // v1.17.5
        "symfony/form": "5.3.*", // v5.3.8
        "symfony/framework-bundle": "5.3.*", // v5.3.8
        "symfony/monolog-bundle": "^3.0", // v3.7.0
        "symfony/property-access": "5.3.*", // v5.3.8
        "symfony/property-info": "5.3.*", // v5.3.8
        "symfony/rate-limiter": "5.3.*", // v5.3.4
        "symfony/runtime": "5.3.*", // v5.3.4
        "symfony/security-bundle": "5.3.*", // v5.3.8
        "symfony/serializer": "5.3.*", // v5.3.8
        "symfony/stopwatch": "5.3.*", // v5.3.4
        "symfony/twig-bundle": "5.3.*", // v5.3.4
        "symfony/ux-chartjs": "^1.3", // v1.3.0
        "symfony/validator": "5.3.*", // v5.3.8
        "symfony/webpack-encore-bundle": "^1.7", // v1.12.0
        "symfony/yaml": "5.3.*", // v5.3.6
        "symfonycasts/verify-email-bundle": "^1.5", // v1.5.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.3
        "twig/string-extra": "^3.3", // v3.3.3
        "twig/twig": "^2.12|^3.0" // v3.3.3
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.0
        "symfony/debug-bundle": "5.3.*", // v5.3.4
        "symfony/maker-bundle": "^1.15", // v1.34.0
        "symfony/var-dumper": "5.3.*", // v5.3.8
        "symfony/web-profiler-bundle": "5.3.*", // v5.3.8
        "zenstruck/foundry": "^1.1" // v1.13.3
    }
}