Laravel 教程:实现屏蔽用户 / 禁止访问功能
Laravel Auth系统有不少新特性,这些特性中不包括屏蔽用户一段时间的功能,比如把喷子关小黑屋14天让他冷静一下。幸运的是,用中间件来实现这个功能很简单。本文会告诉你怎么做。
以下画面是被禁止的用户尝试登陆的时候看到的样子:
第一步 新字段:users.banned_until
我们不要仅仅让屏蔽用户在is_banned字段上是个布尔值,我建议用timestamp 类型字段。如果这个字段为空,用户是不是被屏蔽的,反之字段上面的值就是喷子的解封之日。
举个栗子,我们在一个全新的Laravel 5.7项目中执行默认的迁移文件,并且命令行中执行make:auth。接着,我们使用下面的命令行添加一个新字段:
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();
});
}
目前所有用户都会有这个值默认为空的字段,这样就不会有人在执行完这个迁移文件后被自动屏蔽,这是安全操作。
我们还需要把这个字段添加到用户模型的白名单 $fillable字段里。为了方便,这个字段也写到 $dates 数组里。稍后我们会利用到某些Carbon操作。
class User extends Authenticatable
{
protected $fillable = [
'name', 'email', 'password', 'banned_until'
];
protected $dates = [
'banned_until'
];
}
本文中,我会跳过有关用户管理员封锁/解封用户的部分。你可以通过我们的生成器生成用户管理系统 QuickAdminPanel.com。
本文中,我们假设某些管理员在某个地方可以在users.banned_until这个字段上写入时间戳或者置空。甚至就直接在数据库软件Sequel Pro或phpMyAdmin中操作。
第二步 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() 方法显示名词的单数形式还是复数形式,具体取决于数字。
第三步:使用中间件并显示错误信息
接下来,我们需要注册这个中间件并且过滤所有的请求。所以将它添加到 app/Http/Kernel.php 文件全局中间件组 web:
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') }}">
...
效果如下:
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
这个功能挺好
return redirect()->route('login')->withMessage($message); 总是跳转不到登录页而是首页怎么回事