Middleware for Route Protection
Middleware is introduced as a maintainable way to protect specific routes instead of duplicating logic in controllers. It enables composability by allowing multiple middleware functions to be chained together.
Authentication Middleware
An authentication cookie containing user ID and authentication status is checked on each protected request. If the user is not authenticated, they are redirected to the login page. Since the cookie is encrypted and authenticated, its contents can be trusted.
Rate Limiting Login Attempts
To prevent brute-force attacks, login attempts are limited based on IP address. After a defined number of failed attempts, a cooldown period (e.g., 10–15 minutes) is enforced.
Storage Strategy for Rate Limiting
In-memory storage is used to track login attempts, which is sufficient for a small personal application. Alternatives like databases or Redis can be implemented for more robust or scalable solutions.
Protection Against Denial of Service
IP-based rate limiting prevents attackers from repeatedly attempting logins to lock out legitimate users. The attacker can only block their own IP, reducing the risk of service disruption.
Securing Admin Pages
By combining authentication and rate-limiting middleware, all admin routes can be securely restricted to authorized users only.
Okay, so we can create a user and securely store their password or in our case, our password, and we can validate that the password is correct. We still need to lock down certain routes and to do that, we're going to be using middleware. We've already talked about middleware when we did flash messages, but I want to touch upon why it really matters because we could
technically just add the same logic that we're going to be adding to the middleware here to the controllers that has to be protected. But this is not really maintainable. The logic is going to stay the same, so it's a nice way to have some usability and composability because we can chain multiple middlewares together. You will see how we are going to be chaining an IP rate limiter and an off only check rate limiter.
and we're gonna be using much of the same techniques as we did with flash messages. We just need to create a, we're gonna call it app user or something like that, where we have an ID and is authenticated. And then we will have a middle by the checks that cookie on each request to the lockdown pages. And what it will do is check the value. If the value is authenticated is not set to true, then we simply just redirect them to the login page.
And since we know that the cookie comes from us because we are encrypting and authenticating the cookie, we can trust the values inside that cookie. But it's not enough to just have this authentication cookie. We also want to wait limit login attempts because we could technically have a hacker just try thousands or millions of passwords and then
Even when we're using something like Argon2ID, they could technically crack the account with weak passwords. So the IP limiter will look up the IP address and then count how many attempts has been made to log in. And then let's say they hit something like five or 10 attempts, then there will be a cooldown period implemented for that IP. If you simply have an in-memory storage, that will check.
how many times an IP has tried to log in. If they reach the limit, we will implement a cooldown period for that IP of, say, 10 or 15 minutes. We could also do some gradual throttling, but maybe it becomes a little bit out of scope for what we need here. So for the storage consideration, we'll be using in-memory storage, as I just mentioned. We could also use password storage. We can use Redis or something akin to Redis.
of our needs in memory is gonna be more than enough. This is our own personal block. We probably will not get a huge attacks against that. We would also probably not need to know what kinds of IP addresses are attacking us because it's very unlikely that we get these kind of attacks against our own personal block. You can always re-implement this to store those attempts in the database or in Redis if you want to. It can be a little
side thing you can try out to add to your own blog. We also protect against something called denial of service, which means that if an attacker figured out the email that we use or the username that we use, they could just continually try to log in and intensely log us out from our own account. So by using the IP address, the attacker can only lock themselves out. Right.
So to sum up, we are going to be adding an authentication middleware or authentication only middleware. We're going to add a rate limiting middleware. And with those two things in place, we can lock down all of the admin pages and ensure that only we or the users that we allow onto the admin or the blog can actually interact with these lockdown pages.