用php实现登录日志,利用Laravel事件系统如何实现登录日志的记录详解
本文介紹的是利用Laravel事件系統實現登錄日志記錄的相關內容,分享出來給大家參考,下面來看看詳細的介紹:
明確需求
記錄一個登錄日志,通常需要下列信息:
客戶端Agent信息
客戶端IP地址
訪問IP地點
登錄時間
登錄用戶信息
確立工具
明確完需求后,根據每個需求查找自己所需的工具吧。
需求1 jenssegers/agent就可以滿足我們要求
需求2 Laravel下直接Request::getClientIp()
需求3 zhuzhichao/ip-location-zh這個包可以滿足要求
需求4 time()
需求5 登錄用戶模型
開工
采用Laravel的事件訂閱系統來實現,需要實現一個登錄事件和一個登錄事件監聽器。
生成事件和監聽器
Laravel命令行支持自動生成事件和監聽器,在App\Providers\EventServiceProvider中添加需要實現的事件:
protected $listen = [
...,
//添加登錄事件及對應監聽器,一個事件可綁定多個監聽器
'App\Events\LoginEvent' => [
'App\Listeners\LoginListener',
],
];
運行命令:php artisan event:generate就會自動生成事件和監聽器,已存在的事件和監聽器不會發生改變。
登錄事件(Event)
回顧下需求,我們的登錄事件需要的5點信息,在事件中需要記錄這些信息,所以事件設計如下:
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;
/**
* @var User 用戶模型
*/
protected $user;
/**
* @var Agent Agent對象
*/
protected $agent;
/**
* @var string IP地址
*/
protected $ip;
/**
* @var int 登錄時間戳
*/
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');
}
}
在事件中記錄所需要的信息,并實現這些信息的get方法。
登錄監聽器(Listener)
在監聽器中,獲取到事件傳遞過來的信息,把這些信息記錄到數據庫中,實現如下:
namespace App\Listeners;
use App\Events\LoginEvent;
class LoginListener
{
// handle方法中處理事件
public function handle(LoginEvent $event)
{
//獲取事件中保存的信息
$user = $event->getUser();
$agent = $event->getAgent();
$ip = $event->getIp();
$timestamp = $event->getTimestamp();
//登錄信息
$login_info = [
'ip' => $ip,
'login_time' => $timestamp,
'user_id' => $user->id
];
// zhuzhichao/ip-location-zh 包含的方法獲取ip地理位置
$addresses = \Ip::find($ip);
$login_info['address'] = implode(' ', $addresses);
// jenssegers/agent 的方法來提取agent信息
$login_info['device'] = $agent->device(); //設備名稱
$browser = $agent->browser();
$login_info['browser'] = $browser . ' ' . $agent->version($browser); //瀏覽器
$platform = $agent->platform();
$login_info['platform'] = $platform . ' ' . $agent->version($platform); //操作系統
$login_info['language'] = implode(',', $agent->languages()); //語言
//設備類型
if ($agent->isTablet()) {
// 平板
$login_info['device_type'] = 'tablet';
} else if ($agent->isMobile()) {
// 便捷設備
$login_info['device_type'] = 'mobile';
} else if ($agent->isRobot()) {
// 爬蟲機器人
$login_info['device_type'] = 'robot';
$login_info['device'] = $agent->robot(); //機器人名稱
} else {
// 桌面設備
$login_info['device_type'] = 'desktop';
}
//插入到數據庫
DB::table('login_log')->insert($login_info);
}
}
這樣,監聽器就完成了,每次一觸發登錄事件,就會在數據庫中添加一條登錄信息。
觸發事件
通過全局的event()方法來觸發事件,event()方法的參數為事件實例:
namespace App\Controllers;
...
use App\Events\LoginEvent;
use Jenssegers\Agent\Agent;
class AuthControoler extends Controller
{
...
public function login(Request $request)
{
//登錄實現
...
//登錄成功,觸發事件
event(new LoginEvent($this->guard()->user(), new Agent(), \Request::getClientIp(), time()));
...
}
}
隊列化監聽器
有時監聽器會進行一些耗時操作,這時應該結合Laravel的隊列系統將監聽器進行隊列化,前提是已經配置了隊列并開啟了隊列處理器。
隊列化非常簡單,只需監聽器實現ShouldQueue接口即可,即:
namespace App\Listeners;
...
use Illuminate\Contracts\Queue\ShouldQueue;
class LoginListener implements ShouldQueue
{
/**
* 失敗重試次數
* @var int
*/
public $tries = 1;
...
}
總結
Laravel的事件系統實現起來還是非常優雅的,同一個事件可以很方便的添加各類監聽器,且各個監聽器之間互不干擾,解耦性非常強。加上隊列系統,可以很方便的處理一些后續任務。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
總結
以上是生活随笔為你收集整理的用php实现登录日志,利用Laravel事件系统如何实现登录日志的记录详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java搭建聊天服务器_使用 Serve
- 下一篇: php-7.2.13的安装,php7.2