发布于 5年前

在Laravel项目中如何对用户永久封号,或禁止一段时间

Laravel Auth系统有很多功能,但它不包括对用户封号一段时间,比如对一些不友好的论坛用户禁言14天。使用Middleware可以很轻松的实现。

1. 新字段:users.banned_until

字段类型为:时间戳,如果它是空的,那么用户不被禁止,否则代表禁止到何时。

生成迁移文件:

php artisan make:migration add_banned_until_to_users_table

迁移文件内容:

class AddBannedUntilToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->timestamp('banned_until')->nullable();
        });
 }

所有已存在的用户都将字段设置为NULL,因此在迁移后不会默认自动禁止任何人。

我们还需要在app/User.php模型中将该字段添加到$fillable数组中。为方便起见,我们也将它放入$dates数组中。稍后会做一些Carbon操作。

class User extends Authenticatable
{
    protected $fillable = [
        'name', 'email', 'password', 'banned_until'
    ];

    protected $dates = [
        'banned_until'
    ];
}

我们假设某个管理员某处将users.banned_until的值作为timestamp或NULL。

2. 中间件:CheckBanned

我们将创建一个中间件来检查用户是否被禁止。在这种情况下,我们将该用户注销并重定向到登录页面并显示错误消息。

php artisan make:middleware CheckBanned

这是文件app/Http/Middleware/CheckBanned.php

class CheckBanned
{
    public function handle($request, Closure $next)
    {
        if (auth()->check() && auth()->user()->banned_until && now()->lessThan(auth()->user()->banned_until)) {
            $banned_days = now()->diffInDays(auth()->user()->banned_until);
            auth()->logout();

            if ($banned_days > 14) {
                $message = 'Your account has been suspended. Please contact administrator.';
            } else {
                $message = 'Your account has been suspended for '.$banned_days.' '.str_plural('day', $banned_days).'. Please contact administrator.';
            }

            return redirect()->route('login')->withMessage($message);
        }

        return $next($request);
    }
}

这里有几点需要注意:

  • 我们使用一些Carbon方法(如 lessThan()diffInDays())来执行日期操作。这就是为什么早些时候我们需要在User模型中添加 banned_until 字段作为 $dates 属性。
  • 如果用户被封号14天或更短时间,我们会显示剩余的封号天数。否则我们假设帐户被永久禁止。
  • 不确定你是否知道 str_plural()方法显示名词的单数或复数形式,具体取决于数字。

3. 使用中间件和显示错误消息

接下来,我们需要注册此中间件并在每个请求上运行,因此我们将其类添加到名为web的app/Http/Kernel.php文件组:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,

        // ... other middleware classes

        \App\Http\Middleware\CheckBanned::class,
    ],

最后,让我们在resources/views/auth/login.blade.php中添加消息:

...

<div class="card-body">

    @if (session('message'))
        <div class="alert alert-danger">{{ session('message') }}</div>
    @endif

    <form method="POST" action="{{ route('login') }}">

...
©2020 edoou.com   京ICP备16001874号-3