Clear requirements

To record a login log, the following information is usually required:

  1. Client Agent information
  2. IP address of the client
  3. Accessing IP locations
  4. The login time
  5. Login User Information

Establish tools

Once you’ve identified your requirements, find the tools you need for each requirement.

  • Requirement 1 jenssegers/ Agent can meet our requirements
  • Demand for 2LaravelUnder the directRequest::getClientIp()
  • Zhuzhichao /ip-location-zh this package can meet the requirements
  • Demand for 4time()
  • Requirement 5 Login user model

starts

Laravel’s event subscription system is used to implement a login event and a login event listener.

Generate events and listeners

The Laravel command line supports automatic event generation and listener generation. Add the required event to App\Providers\EventServiceProvider:

Protected $listen = [..., // Add Listeners and Events to the process. [App\Events\LoginEvent' => ['App\ LoginListener',],];Copy the code

Run the PHP artisan event:generate command to automatically generate events and listeners. The existing events and listeners will not change.

Login Events

To review the requirements, we need five points of information for our login event, which needs to be recorded in the event, so the event design is as follows:

namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Broadcasting\InteractsWithSockets; use App\Models\User; use Jenssegers\Agent\Agent; class LoginEvent { use Dispatchable, InteractsWithSockets, SerializesModels; /** * @user User model */ protected $User; /** * @var Agent */ protected $Agent; /** * @var string IP address */ protected $IP; /** * @timestamp */ protected $timestamp; Public function __construct($user, $agent, $IP, $timestamp) {$this->user = $user; $this->agent = $agent; $this->ip = $ip; $this->timestamp = $timestamp; } public function getUser() { return $this->user; } public function getAgent() { return $this->agent; } public function getIp() { return $this->ip; } public function getTimestamp() { return $this->timestamp; } /** * Get the channels the event should broadcast on. * * @return Channel|array */ public function broadcastOn() { return new PrivateChannel('channel-default'); }}Copy the code

Record the required information in the event and implement a GET method for this information.

Login Listener

In the listener, get the information from the event, record the information to the database, implement as follows:

namespace App\Listeners; use App\Events\LoginEvent; Public function handle(LoginEvent $event) {$user = $event->getUser(); $agent = $event->getAgent(); $ip = $event->getIp(); $timestamp = $event->getTimestamp(); / / login information $login_info = [' IP '= > $IP,' login_time '= > $timestamp,' user_id '= > $user - > id); Zhuzhichao /ip-location-zh $addresses = \ IP ::find($IP); $login_info['address'] = implode(' ', $addresses); $login_info['device'] = $agent->device(); $agent = $agent->browser(); $login_info['browser'] = $browser . ' ' . $agent->version($browser); $platform = $agent->platform(); $login_info['platform'] = $platform . ' ' . $agent->version($platform); / / operating system $login_info [' language '] = the implode (', '$agent - > languages ()); / / / / device type if ($agent - > isTablet ()) {/ / tablet $login_info [' device_type] = 'tablet'; } else if ($agent->isMobile()) {$login_info['device_type'] = 'mobile'; } else if ($agent->isRobot()) {$agent->isRobot(); $login_info['device'] = $agent->robot(); $login_info['device_type'] = 'desktop'; } / / inserted into the database DB: : the table (' login_log) - > insert ($login_info); }}Copy the code

This completes the listener, adding a login message to the database each time a login event is triggered.

Triggering event

Events are emitted via the global event() method, which takes an event instance:

namespace App\Controllers; . use App\Events\LoginEvent; use Jenssegers\Agent\Agent; class AuthControoler extends Controller { ... Public function login(Request $Request) { $this->guard()->user(), new Agent(), Request::getClientIp(), time())); . }}Copy the code

Queued listeners

Sometimes listeners perform time-consuming operations and should be queued in conjunction with Laravel’s queue system, provided that queues are configured and queue handlers are enabled.

Queueing is as simple as implementing the ShouldQueue interface:

namespace App\Listeners; . use Illuminate\Contracts\Queue\ShouldQueue; Class LoginListener implements ShouldQueue {@var int */ public $tries = 1; . }Copy the code

conclusion

Laravel event system is very elegant to implement, the same event can be very convenient to add all kinds of listeners, and each listener does not interfere with each other, decoupling is very strong. In addition to the queue system, it is very convenient to handle some follow-up tasks.