обработка событий входа в 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, но я знаю, что это не так, как должно быть.

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

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

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

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

 $ php artisan handler:event AuthLoginEventHandler 

Затем я изменил сгенерированный класс, удалив импорт класса Event и импортировав модель пользователя. Я также передал User $user и $remember метод handle, поскольку при запуске события 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, используя класс обработчика событий!

В 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', ], ]; 

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

Будьте осторожны, спрашивая, что лучший способ сделать 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 в конструктор, то событие не обязательно должно знать о договоре фазового фасада / охраны. Это означает, что наш UserLoggedIn события UserLoggedIn не тесно связан с Eloquent или какой-либо UserLoggedIn аутентификации, которую вы решили использовать в своем приложении. В любом случае, давайте добавим этот параметр 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 наш новый обработчик событий UpdateUserMetaData и 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) { // } } 

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

 <?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.

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

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

Чтобы завершить первый шаг, нам просто нужно добавить наши классы событий в свойство $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)); 

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

Для 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', ], ]; 

Откройте 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

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

  <?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('Ymd H:i:s') )); }); // } }