扩展Laravel认证组件功能

Laravel 自带的 认证组件 很方便,集成了常用的认证相关的功能,满足项目开发的基本需求,但一些常用的功能却没有,这篇文章将会介绍如果增加一些常见的基础功能。

在开始之前,需要先生成认证组件,在命令行中使用如下命令即可:

1
php artisan make:auth

验证码

验证码可以说是网站中最常见的一个功能,以前的图形验证码已经很落后,现在,很多厂商都开发了新一代的验证码,这篇文章主要来说明 极验验证码

极验验证码的最新版本是 v3.0,在之前的版本中,我一直使用的是 Germey/LaravelGeetest,不过最新版的代码还没有更新到 v3.0,所以我参照这个扩展,结合官方的 3.0SDK 自己制作了一个 轮子,下面就开始扩展认证组件的验证码功能。

引入扩展包

  1. 安装包文件

    1
    $ composer require jormin/laravel-geetest
  1. 注册 ServiceProvider:

    1
    Jormin\Geetest\GeetestServiceProvider::class,
  2. 添加 Alias

    1
    'Geetest' => Jormin\Geetest\Facades\Geetest::class,
  3. 创建配置文件、视图级资源文件:

    1
    php artisan vendor:publish --provider='Jormin\Geetest\GeetestServiceProvider'
  1. .env 文件增加配置项 GEETEST_IDGEETEST_KEY

  2. 自定义配置项

修改项目代码

  1. 前端页面验证

    在页面 \resources\views\auth\login.blade.php 的登录表单中增加如下代码

    1
    {!! Geetest::render() !!}
  2. 服务端页面二次验证

    修改 app\Http\Controllers\Auth\LoginController.php 文件,覆盖 Trait AuthenticatesUsersvalidateLogin 函数,完整代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
    * Validate the user login request.
    *
    * @param \Illuminate\Http\Request $request
    * @return void
    */
    protected function validateLogin(Request $request)
    {
    $this->validate($request, [
    $this->username() => 'required',
    'password' => 'required',
    'geetest_challenge' => 'required|geetest',
    ], [
    'geetest' => config('laravel-geetest.server_fail_alert')
    ]);
    }

至此,极验验证码就引入到项目的登录流程中了,其他地方需要使用的话方法类似。

登录日志

项目中经常需要对用户的登录信息做些统计,用于后期的数据分析,比如账号安全鉴定,活跃时常统计等等。

最基本登录日志包含登录时间、退出时间及登录地址,登录时间和退出时间我们可以监听认证组件的一些事件来处理,登录地址可以通过反查IP来处理。

创建登录记录模型及迁移文件

  1. 我们来创建数据模型及迁移文件,在命令行中使用如下命令即可, 生成的迁移文件存储在 database\migrations 目录下。

    1
    php artisan make:model Models/SigninLog -m
  1. 修改生成的迁移文件 2017_04_26_081110_create_signin_logs_table,加入基本的统计字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
    Schema::create('signin_logs', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('user_id')->comment("用户ID")->unsigned();
    $table->string('ip',15)->comment("IP地址");
    $table->string('ip_area')->comment("IP地区");
    $table->timestamp('login_time')->comment("登录时间");
    $table->timestamp('logout_time')->comment("退出时间")->nullable();

    $table->foreign('user_id')->references('id')->on('users')
    ->onUpdate('cascade')->onDelete('cascade');
    });
    }
  2. 运行迁移文件:

    1
    php artisan migrate
  3. 修改模型文件,增加批量赋值属性:

    1
    2
    3
    4
    5
    6
    7
    8
    /**
    * The attributes that are mass assignable.
    *
    * @var array
    */
    protected $fillable = [
    'user_id','ip','ip_area','login_time'
    ];

生成认证组件的监听类

  1. 配置监听类

    认证组件 提供了一些认证相关的事件,这里我们只需要监听 登录成功退出成功 事件即可。

    app\Providers\EventServiceProvider.php 文件中配置我们要监听的事件以及相关的监听类,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
    * The event listener mappings for the application.
    *
    * @var array
    */
    protected $listen = [
    // 登录监听
    'Illuminate\Auth\Events\Login' => [
    'App\Listeners\LogSuccessfulLogin',
    ],

    // 退出监听
    'Illuminate\Auth\Events\Logout' => [
    'App\Listeners\LogSuccessfulLogout',
    ],

    ];
  2. 生成配置的监听类

    在命令行中使用如下命令,生成的监听类存放于 app\Listeners 目录中。

    1
    php artisan event:generate

记录登录时间和IP。

接下来我们先记录用户的登录时间。LogSuccessfulLogin.phphandle 函数的参数是一个 Illuminate\Auth\Events\Login 对象,包含用户对象信息,所以这里我们只需要记录用户的登录时间和IP信息即可。

  1. 使用Carbon类生成当前时间。

    1
    $login_time = Carbon::now();
  2. 获取访问IP并转换地址

    获取IP:

    1
    $ip = request()->getClientIp();

    反查IP可以使用 IPIP 的服务,我已经将服务封装了一个扩展包 jormin/laravel-ip,这里我们使用这个扩展包即可。

    引入扩展包

    1
    $ composer require jormin/laravel-ip
反查IP,反查的结果是一个数组,需要拼成字符串:

1
$ip_area = implode(Jormin\IP\IP:ip2addr($ip),' ');
至此,用户的登录信息就记录完成了,完整代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Handle the event.
*
* @param Login $event
* @return void
*/
public function handle(Login $event)
{
$user = $event->user;
$login_time = Carbon::now();
$login_ip = request()->getClientIp();
$login_ip_area = implode(IP::ip2addr($login_ip),' ');

SigninLog::create([
'user_id' => $user->id,
'ip' => $login_ip,
'ip_area' => $login_ip_area,
'login_time' => $login_time
]);
}

记录退出时间

退出时间和登录时间记录的方式类似,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Handle the event.
*
* @param Logout $event
* @return void
*/
public function handle(Logout $event)
{
$user = $event->user;
$signinLog = SigninLog::where('user_id',$user->id)->orderBy('id','desc')->first();
if($signinLog){
$signinLog->logout_time = Carbon::now();
$signinLog->save();
}
}

本文作者:Jormin
本文地址https://blog.lerzen.com/2017/04/26/扩展laravel认证组件功能/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!

----- 到这结束咯 感谢您的阅读 -----