Laravel password expired: force change password every 30 days

In some systems it is required to change password every X days: in banking sector, or working with more sensitive data. Laravel doesn’t have that functionality out-of-the-box, but it’s easy to build. Let’s do it today.

Here’s what I mean by “expired password” page. When user logs in, they will see something like this:

laravel password expired

To build this functionality, we will go through following steps:

  1. Add timestamp field “password_changed_at” to users DB table
  2. Build that page to force reset password: route/controller/view
  3. Process password reset, also validation on current password and new passwords
  4. Create middleware to check whether password has expired (was unchanged in X days)
  5. Add that middleware to Http Kernel and to Routes
  6. Final small details: make X days configurable from config file

So, let’s begin?

Step 1. Password_changed_at field

First, we add this migration:

Then we need to make it fillable, so we edit app/User.php:

Step 2. Page to force reset password

We will almost copy-paste current Reset Password page into separate MVC structure.


New controller app/Http/Controllers/Auth/ExpiredPasswordController.php:

And new view resources/views/auth/password/expired.blade.php – see above:

At this point, we should see this:

laravel password expired

Now, how do we process the password change? POST request goes to route password.post_expired, so let’s implement that one.



As you may have noticed, for validation I’ve created a separate Request class in app/Http/Requests/PasswordExpiredRequest.php:

Step 3. Middleware to check expired password

Ok, now we have a page to reset the expired password, and after the reset we set the field password_changed_at. Now, time to actually use that field and check when the password was actually reset.

Let’s assume that after logging in, user will go to some dashboard:

Let’s wrap it in auth middleware and Route Group:

Now, we need to add those previous routes under auth as well, cause you can change your password only if you’re logged in, right?

So we have this:

Final step here – introducing our own middleware to check the expired password. It should be called on all internal pages, for now we have only the dashboard, but in the future pages should be created under that special sub-group with password_expired middleware:

Final routes/web.php:

Now, let’s create our middleware:

And then we fill app/Http/Middleware/PasswordExpired.php:

Basically, we’re checking when the password was changed (if ever, otherwise we take users.created_at), and if it’s older than 30 days – we redirect to password expired page, that we’ve created above.

To make that middleware work, we need to register it in app/Http/Kernel.php:

The final mini-step in this whole function is to make that 30 days configurable. It’s pretty easy – we just need to add a parameter into array of some config file – logically, we choose config/auth.php and add this line there:

Then we edit our middleware to use this value. Instead of:

We have this:

I guess, that’s it! Now you can force your users to change your passwords every 30 days or so.

Check out my new online course: Laravel Eloquent: Expert Level

7 thoughts on “Laravel password expired: force change password every 30 days

  1. If website force me to change my passwd, I must think a new passwd that i don’t familiar with it, I would forgot it for a while, Next Time when i login…. WTF

  2. Is there any check for the new password to be different from the existing one? You should put a condition for this otherwise one can still post the same password and it will update.

  3. at app/Http/Requests/PasswordExpiredRequest.php you have done like class PasswordExpiredRequest extends FormRequest. but where is the programmatically implementation of FormRequest class? can you please explain me.?

  4. Hi,

    Ive managed to make it work on my local PC, but when i move the code to the client side. it run for ever and die saying there is too much redirect. i am using lavarel 5.3. can you please me to fix this?

Leave a Reply

Your email address will not be published. Required fields are marked *