How to Save User’s Last Login Time and IP Address

Quick tip of the day. Default Laravel Auth comes with User table and model, but without logging capability, so we need to build it ourselves. Fortunately, it’s very easy, I will show you one method.

Let’s say that we want to save user’s last login time and IP address in the same users table.
So we start with database migration:

php artisan make:migration add_login_fields_to_users_table

Then we fill it with these fields:

class AddLoginFieldsToUsersTable extends Migration
{

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->datetime('last_login_at')->nullable();
            $table->string('last_login_ip')->nullable();
        });
    }

    // ...

Next, we need to add these fields as fillables in app/User.php model:

class User extends Authenticatable
{
    protected $fillable = [
        'email',
        'password',
        'name',
        'last_login_at',
        'last_login_ip',
    ];

    // ...

Finally, how do we fill them in? You need to know that there is authenticated() method in the AuthenticatesUsers trait. It’s called every time someone logs in.

/**
 * The user has been authenticated.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $user
 * @return mixed
 */
protected function authenticated(Request $request, $user)
{
    //
}

In trait this method is empty. So we have freedom to override it in LoginController and add whatever code we need.

app/Http/Controllers/Auth/LoginController.php:

function authenticated(Request $request, $user)
{
    $user->update([
        'last_login_at' => Carbon::now()->toDateTimeString(),
        'last_login_ip' => $request->getClientIp()
    ]);
}

And, that’s it! Here’s what we have in users table after log in:

laravel last login ip address

Like our articles?
Check out our Laravel online courses!

17 COMMENTS

  1. What other things may be interesting to collect that you could collect on Login? I really like this! Thank you!

  2. When a password reset is performed the user is automatically logged in. This method is then not triggered. An event listener is maybe a better solution or what do you think?

    • Hi Leslie, same thing about registering – user is automatically logged in and this event isn’t triggered. Perhaps you’re right, even listener somewhere “deeper” could be better but you need to know what events to listen to.

  3. I hope you guys noticed that the updated_at column gets the same value always as last_login_at column. It shouldn’t be so.

    • updated_at column should be different to last_login_at when you change your password or another personal data under users table.

  4. This was helpful, however as of Laravel 5.8.11 this code throws an error since Request is not an instance of Auth\Request.

    Anyway, if you want just to save the login and not trigger the updated_at filed, just do :

    function authenticated()
    {
    DB::table(‘users’)->where(‘id’, Auth::user()->id)->update([‘last_login_at’=>Carbon::now()->toDateTimeString()]);
    }

      • You can, still for me it does not work proprerly – field does not get updated. First time I’v tried it, since it relies on the User model, it updated also the updated_at field, which is a undesirable side effect. DB interface do it properly. Or I’m missing something

        • Probably you’re missing something, it worked for me and many others. But maybe something changed in Laravel 5.7/5.8. Anyway, if DB interface works for you, great.

        • Kyobul, you should disable the timestamp like this to avoid updating the updated_at field-

          $user->timestamps = false;
          $user->last_login_at = Carbon::now()->toDateTimeString();
          $user->last_login_ip = $request->getClientIp();
          $user->save();

LEAVE A REPLY

Please enter your comment!
Please enter your name here