Clear requirements
To record a login log, the following information is usually required:
- Client Agent information
- IP address of the client
- Accessing IP locations
- The login time
- 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 2
Laravel
Under the directRequest::getClientIp()
- Zhuzhichao /ip-location-zh this package can meet the requirements
- Demand for 4
time()
- 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.