Я пытаюсь подключиться к логину даже в моем приложении 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.
Нам нужно сопоставить событие с обработчиком события в классе EventServiceProvider
в 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));
И все готово! Я тестировал этот код, когда писал этот ответ, не стесняйтесь задавать вопросы, если у вас есть.
Для 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') )); }); // } }