Обработка событий входа в laravel 5

Я пытаюсь подключиться к логину даже в своем приложении L5, чтобы установить последнее время входа и IP-адрес. я могу заставить его работать со следующим:

Event::listen('auth.login', function($event)
{
    Auth::user()->last_login = new DateTime;
    Auth::user()->last_login_ip = Request::getClientIp();
    Auth::user()->save();
});

однако, мне интересно, какой лучший способ сделать это в L5 - с объектом обработчика события. Я попытался создать обработчик событий и добавить auth.login в качестве ключа массива в службе событий, но это не сработало. im not sure, если это возможно или нет с событием auth.login. если это не так, где самое подходящее место для размещения вышеуказанного кода. для тестирования я помещаю его в файл routes.php, но я знаю, что это не так, как должно быть.

Ответ 1

EDIT: это работает только в 5.0. * и 5.1. *.

Для решения 5.2. * см. ответ JuLiAnc ниже.

после работы с обоими предложенными ответами, и еще несколько исследований я наконец понял, как это сделать, как я пытался вначале.

Я выполнил следующую команду artisan

$ php artisan handler:event AuthLoginEventHandler

Затем я изменил сгенерированный класс, удалив импорт класса Event и импортировав модель пользователя. Я также передал методы User $user и $remember методу дескриптора, так как при запуске события auth.login это передается.

<?php namespace App\Handlers\Events;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use App\User;

class AuthLoginEventHandler {

    /**
     * Create the event handler.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  User $user
     * @param  $remember
     * @return void
     */
    public function handle(User $user, $remember)
    {
        dd("login fired and handled by class with User instance and remember variable");
    }

}

теперь я открыл EventServiceProvided.php и изменил массив $listen следующим образом:

protected $listen = [
    'auth.login' => [
        'App\Handlers\Events\AuthLoginEventHandler',
    ],
];

Я понял, что если это не работает сначала, вам может понадобиться

$ php artisan clear-compiled

Мы идем! теперь мы можем отвечать на вход пользователя через событие auth.login с помощью класса обработчика событий!

Ответ 2

В laravel 5.2; auth.login не будет работать... необходимо использовать следующее:

protected $listen = [
    'Illuminate\Auth\Events\Attempting' => [
        'App\Listeners\LogAuthenticationAttempt',
    ],

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],

    'Illuminate\Auth\Events\Lockout' => [
        'App\Listeners\LogLockout',
    ],
];

Как указано в документации здесь

Ответ 3

Будьте осторожны, спрашивая, что лучший способ сделать X, потому что Laravel, в частности, предоставляет множество способов выполнения одной и той же задачи - некоторые из них лучше других в определенных ситуациях.

Взглянув на документацию Laravel, лично я бы пошел с "Основным использованием", поскольку он, похоже, соответствует заявлению, о котором вы заявили.

Если мы запустим следующую команду Artisan, мы можем сгенерировать шаблон для события UserLoggedIn.

$ php artisan make:event UserLoggedIn

(обратите внимание на прошедшее время, поскольку события происходят, а затем абоненты уведомляются о произошедшем событии)

(примечание 2: строка app в пространствах имен - это то, что Laravel использует из коробки, это, вероятно, будет отличаться для вас, если вы выполнили команду php artisan app:name)

Для нас генерируется следующий класс:

<?php namespace app\Events;

use app\Events\Event;

use Illuminate\Queue\SerializesModels;

class UserLoggedIn extends Event {

    use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

}

Если мы добавим параметр userId к конструктору, то событие не обязательно должно знать о контракте Fach Facade/Guard. Это означает, что наш код события UserLoggedIn не тесно связан с Eloquent или какой-либо платформой аутентификации, которую вы решили использовать в своем приложении. В любом случае добавьте параметр userId.

<?php namespace app\Events;

use app\Events\Event;
use app\User;

use Illuminate\Queue\SerializesModels;

class UserLoggedIn extends Event {

    use SerializesModels;

    public $userId;

    /**
     * Create a new event instance.
     *
     * @param int userId the primary key of the user who was just authenticated.
     *
     * @return void
     */
    public function __construct($userId)
    {
        $this->userId = $userId;
    }

}

Теперь вам, наверное, интересно, хорошо, что все отлично, но как нам действовать на этом мероприятии? Отличный вопрос! Нам нужно создать обработчик события для обработки, когда это событие запущено. Теперь сделаем это с помощью Artisan:

$ php artisan handler:event UpdateUserMetaData --event=UserLoggedIn

Назовите наш новый обработчик событий UpdateUserMetaData и сообщите Artisan, что событие, которое мы хотим обработать, - это событие UserLoggedIn.

Теперь у нас есть код, который выглядит так внутри app/Handlers/Events/UpdateUserMetaData.php:

<?php namespace app\Handlers\Events;

use app\Events\UserLoggedIn;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class UpdateUserMetaData {

    /**
     * Create the event handler.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  UserLoggedIn  $event
     * @return void
     */
    public function handle(UserLoggedIn $event)
    {
        //
    }

}

Мы можем обновить метод handle, чтобы иметь возможность обрабатывать это событие, как вы указали выше, довольно легко:

<?php namespace app\Handlers\Events;

use app\Events\UserLoggedIn;

use Illuminate\Http\Request;

class UpdateUserMetaData {

    protected $request;

    /**
     * Create the event handler.
     *
     * @param Request $request
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Handle the event.
     *
     * @param  UserLoggedIn  $event
     */
    public function handle(UserLoggedIn $event)
    {
        $user = User::find($event->userId); // find the user associated with this event
        $user->last_login = new DateTime;
        $user->last_login_ip = $this->request->getClientIp();
        $user->save();
    }

}

В качестве примечания, если вы не знакомы с Carbon, вам может понадобиться изучить его, чтобы вы могли воспользоваться его фантастическим API как вы можете использовать Eloquent created_at и updated_at метки времени на большинстве моделей. Здесь ссылка для того, как сообщить Eloquent, какие поля следует использовать с Carbon: http://laravel.com/docs/master/eloquent#date-mutators.

Мы должны выполнить два заключительных этапа, прежде чем этот код будет работать в вашем приложении Laravel.

  • Нам нужно сопоставить событие с обработчиком события в классе EventServiceProvider в каталоге app/Providers.

  • Нам нужно запустить событие после входа в систему.

Чтобы завершить первый шаг, нам просто нужно добавить наши классы событий в свойство $listeners в app/Providers/EventServiceProvder.php следующим образом:

    UserLoggedIn::class => [
        UpdateUserMetaData::class
    ]

Вышеупомянутое будет работать, если вы импортируете классы внутри класса EventServiceProvider, и используете PHP 5.5. Если вы используете более низкую версию PHP, вам необходимо предоставить полный путь каждому классу в виде строки, подобной этой: 'app/Events/UserLoggedIn' и 'app/Handlers/Events/UpdateUserMetaData'.

Массив $listeners отображает события в соответствующие обработчики.

Хорошо, теперь за последний шаг! В базе кода найдите место аутентификации пользователя и добавьте следующее:

event(new \app\Events\UserLoggedIn(Auth::user()->id));

И все готово! Я тестировал этот код, когда писал этот ответ, не стесняйтесь задавать вопросы, если у вас есть.

Ответ 4

Для 5.2 что-то вроде этого

у слушателей:

use Carbon\Carbon;
use Illuminate\Auth\Events\Login;

class UpdateLastLoginWithIp
{
    public function handle(Login $event)
    {
        $event->user->last_login_at = Carbon::now();
        $event->user->last_login_ip = Request::getClientIp()
        $event->user->save();
    }
}

В EventServiceProvider.php:

protected $listen = [
        'Illuminate\Auth\Events\Login' => [
            'City\Listeners\UpdateLastLoginWithIp',
        ],
    ];

Ответ 5

Откройте EventServiceProvider.php и в режиме загрузки вы можете прослушивать событие 'auth.login' через обратный вызов.

public function boot(DispatcherContract $events)
{
    parent::boot($events);
    $events->listen('auth.login', function() 
    {
        dd('logged in event');
    });
}

Возможно, вы захотите создать прослушиватель, чтобы переместить функцию обратного вызова в другое место. Сделайте это следующим образом http://laravel.com/docs/4.2/events#using-classes-as-listeners

Ответ 6

вот мой подход:
Я сделал для создания обработчика событий, когда пользователь вошел в систему с помощью:

  • Ларавел 5.8

1) Запустите следующую команду Artian
php artisan make:listener Auth/UserLoggedIn --event='Illuminate\Auth\Events\Login' *

Это сделает Listener: UserLoggedIn в папке app\Listeners\Auth\

2) Затем вам нужно добавить этот слушатель в ваш EventServiceProvider: **

...
protected $listen = [
   ...
        'Illuminate\Auth\Events\Login' => [
            'App\Listeners\Auth\UserLoggedIn',
        ],
    ];

Наконец, вы можете сделать журнал, когда пользователь вошел в handle функции, расположенной в UserLoggedIn Listener:

public function handle(Login $event)
    {
        //you have access to user object by using : $event->user
    }
  • Вы можете использовать все другие события Auth, вот возможные события:
'Illuminate\Auth\Events\Registered', 
'Illuminate\Auth\Events\Attempting', 
'Illuminate\Auth\Events\Authenticated', 
'Illuminate\Auth\Events\Login', 
'Illuminate\Auth\Events\Failed',
'Illuminate\Auth\Events\Logout',
'Illuminate\Auth\Events\Lockout',

** Вы можете использовать все эти события в вашем EventServiceProvider: https://laravel.com/docs/5.8/authentication#events

Ответ 7

Обычно это можно сделать, выполнив эти действия, шаг за шагом, для журналов регистрации пользователей

.Во-первых, вы должны иметь Auth Scaffolding

  1. использовать это как событие,
    • "Подсветка\Auth\Events\Login" для события входа в систему
    • "Подсветка\Auth\Events\Logout" для события выхода из системы

расположено событие входа и выхода по адресу:

поставщик\Laravel\Framework\SRC\Осветите\Auth\События

EventServiceProvider.php

protected $listen = [

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LoginLogs',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogoutLogs',
    ],

];


public function boot()
{
    parent::boot();

}
  1. затем, после того как вы закончите для EventServiceProvider, сделайте этот следующий шаг
    • введите эту команду ремесленника php событие ремесленника: создать
    • найдите папку Listener внутри папки приложения, проверьте, содержит ли php файлы LoginLogs и LogoutLogs
  2. создайте свою модель миграции и model

команда: php ремесленник make: миграция create_UserLoginHistory

Файл миграции

public function up()
{
    Schema::create('tbl_user_login_history', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('user_id');
        $table->datetime('login_at')->nullable();
        $table->datetime('logout_at')->nullable();
        $table->string('login_ip')->nullable();
        $table->string('role');
        $table->string('session_id');
        $table->timestamps();
    });
}


public function down()
{
    Schema::dropIfExists('tbl_user_login_history');
}

тогда ваша модель: UserLoginHistory

public $timestamps = false;

protected $table = 'tbl_user_login_history';

protected $fillable = ['user_id','login_at','logout_at','login_ip','role','session_id'];

public function setLogOutLog(){

    $this->where('session_id',request()->session()->getId())->update([
        'logout_at' =>Carbon::now(),
        ]);

}

public function setLogInLog(){
    $this->insert(
        ['user_id' => Auth::user()->id,'login_at' =>Carbon::now(),
        'login_ip'=>request()->getClientIp(),'role' =>Auth::user()->role,
        'session_id'=>request()->session()->getId()
        ]);  
}

4.после процедуры переноса и создания модели предположим, что у вас уже есть роли в таблице пользователей

  1. часть слушателя

Слушатель: LoginLogs Класс

use App\UserLoginHistory;


private $UserLoginHistory; 

public function __construct(UserLoginHistory $UserLoginHistory)
{
  // the initialization of  private $UserLoginHistory; 

    $this->UserLoginHistory = $UserLoginHistory;
}


public function handle(Login $event)
{   
     // from model UserLoginHistory

     $this->UserLoginHistory->setLogInLog();
}

Слушатель: LogoutLogs Class

private $UserLogoutHistory; 

public function __construct(UserLoginHistory $UserLoginHistory)
{
    // the initialization of  private $UserLogoutHistory; 

    $this->UserLogoutHistory = $UserLoginHistory;
}


public function handle(Logout $event)
{
    // from model UserLoginHistory
     $this->UserLogoutHistory->setLogOutLog();
}

после того, как вы проделаете все это, попробуйте войти с помощью Auth

Ответ 8

просто сделал это так

    <?php

namespace App\Providers;

use App\User;
use Auth;
use DB;


use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [

    ];

    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        $events->listen('auth.login', function() 
        {

            DB::table('users')
                -> where('id', Auth::id())
                -> update(array(
                        'last_login'    => date('Y-m-d H:i:s')
                    ));

        });

        //
    }
}