Laravel 5.3 Auth 阻止用户登录

3
我有一个问题,我正在使用Laravel 5.3开发一个小网站,并使用他们的基本身份验证让用户注册和登录。
现在我想要实现以下功能:每个人都可以注册和登录,但如果我(作为管理员)点击一个按钮,我可以“封锁”一个特定的用户(例如,如果他做了一些不允许的事情),我不会完全删除数据库中的行,但是我要确保如果该用户尝试登录,他会收到一条消息,说类似“您无法再登录,您的帐户已被封锁,请联系管理员获取更多信息”。问题是:最佳方法是什么?如果我错了,请纠正我,因为我没有找到内置的东西... 当然,我可以只更改用户表并添加一个名为“blocked”的列,通常设置为false,然后使用按钮将其设置为true,然后在登录时检查此值并(如果为true)显示此消息并禁止登录。这是最好的方法吗?如果是,我需要在哪里检查此值,如何显示消息?如果不是,有更好的方法吗?
5个回答

6

我会按照您的建议来做 - 使用“blocked”或“active”列来指示用户是否能够登录。在过去我曾经类似的事情,检查这个值是否允许登录时,我将默认的登录功能移动到我的LoginController中并稍作修改。我的登录方法如下:

/**
 * Handle a login request to the application.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function login(Request $request)
{
    $this->validateLogin($request);

    $user = User::where('email', $request->email)->firstOrFail();
    if ( $user && !$user->active ) {
        return $this->sendLockedAccountResponse($request);
    }

    if ($this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);

        return $this->sendLockoutResponse($request);
    }

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}

我还添加了这些功能来处理未激活的用户:
/**
 * Get the locked account response instance.
 *
 * @param \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
protected function sendLockedAccountResponse(Request $request)
{
    return redirect()->back()
        ->withInput($request->only($this->loginUsername(), 'remember'))
        ->withErrors([
            $this->loginUsername() => $this->getLockedAccountMessage(),
        ]);
}

/**
 * Get the locked account message.
 *
 * @return string
 */
protected function getLockedAccountMessage()
{
    return Lang::has('auth.locked')
            ? Lang::get('auth.locked')
            : 'Your account is inactive. Please contact the Support Desk for help.';
}

谢谢你的回答。你发布的内容看起来不错,但我该如何将开箱即用的登录功能移动到我的控制器中,以便它使用我提供的内容呢? - nameless
AuthController继承了Illuminate\Foundation\Auth\AuthenticatesUsers的login方法。如果你将该类中的login方法复制到你的AuthController中,Laravel将使用AuthController版本。这样你就可以修改它以适应你的需求。(这是针对Laravel 5.2的,但我相信这些类名在5.3中是相同的) - jackel414
但 AuthController 到底是什么?只是我创建的新控制器吗?它在什么时候被调用?抱歉,有点困惑。 - nameless
对不起,5.3更改了控制器的名称。如果您正在使用Laravel身份验证脚手架,则应将登录方法添加到LoginController(App\Http\Controllers\Auth\LoginController)。 - jackel414
所以我的做法是从AuthenticateUsers中复制函数login,将其覆盖在LoginController中,并添加您提供的if条件以及添加两个方法(sendLockedAccountResponsegetLockedAccountMessage),对吗?在这之前,我会确保有一个按钮将数据库中的locked列设置为true,这就是您的意思吗? - nameless
在我的例子中,新列被称为“active”(当它为“false”时,该用户无法登录),但其他所有内容都是正确的。我已经更新了我的答案,并提供了完整的登录方法,希望能更清楚一些。 - jackel414

1
你可以使用软删除功能。
除了从数据库中实际删除记录外,Eloquent还可以“软删除”模型。当模型被软删除时,它们并没有真正从数据库中删除。相反,一个 deleted_at 属性被设置在模型上并插入到数据库中。如果一个模型有一个非空的 deleted_at 值,则该模型已经被软删除。

1
实际上,我说的是一样的,只是用deleted_at属性代替名为blocked的列。此外,我可能也想要完全从数据库中删除某些内容,所以这不是我想要的。 - nameless
@nameless 软删除正是你所需要的。它已经拥有所有必要的方法,如 forceDelete()withTrashed()trashed()restore() 等等。它还会自动隐藏“被封禁”的用户,使其无法出现在通常的 get()paginate() 等查询中。 - Alexey Mezenin
但是如果启用了软删除,我是否仍然可以完全删除用户?如果我想要删除用户,我该怎么做?如果用户被软删除,我如何在登录时检查并显示消息? - nameless
完全删除用户请使用forceDelete() - Alexey Mezenin
要永久从数据库中删除一个软删除的模型,请使用forceDelete方法:我是否需要先软删除它,然后再使用forceDelete()?还不知道如何在用户登录时检查此帐户是否已被软删除,如果是,则打印此消息(实际上打印它而不是“在数据库中找不到此记录”的消息)。 - nameless
在我的情况下,我尝试了很多方法来注销用户,例如创建中间件BlockedUser并将其应用于我的多重认证。但是没有成功,而这个“软删除”对我来说是完美的解决方案。感谢@AlexeyMezenin。 - arun

0

0

步骤1:

add new field to the User table called ‘status’ (1:enabled, 0:disabed)

步骤2:

to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:

/**
 * Get the needed authorization credentials from the request.
 *
 * @param \Illuminate\Http\Request $request
 * @return array
 */
 protected function credentials(\Illuminate\Http\Request $request)
 {
 $credentials = $request->only($this->username(), ‘password’);

return array_add($credentials, ‘status’, ‘1’);
 }

步骤三:

to block the user when using passport authentication ( token ) , in the User.php model add the following function :

public function findForPassport($identifier) {
     return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
     }

请参考此链接(教程)以帮助您:https://medium.com/@mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810


-1
已解决: 这个链接(教程)会对你有所帮助:https://medium.com/@mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810

步骤1:

add new field to the User table called ‘status’ (1:enabled, 0:disabed)

步骤2:

to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:

/**
 * Get the needed authorization credentials from the request.
 *
 * @param \Illuminate\Http\Request $request
 * @return array
 */
 protected function credentials(\Illuminate\Http\Request $request)
 {
 $credentials = $request->only($this->username(), ‘password’);

return array_add($credentials, ‘status’, ‘1’);
 }

步骤三:

to block the user when using passport authentication ( token ) , in the User.php model add the following function :

public function findForPassport($identifier) {
     return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
     }

完成了 :)


欢迎提供潜在解决方案的链接,但请添加链接周围的上下文,以便其他用户了解它是什么以及为什么存在。在引用重要链接时,请始终引用最相关的部分,以防目标站点无法访问或永久离线。请注意,仅仅是一个外部网站链接可能是为什么和如何删除某些答案?的原因之一。 - FelixSFD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接