ログイン機能に条件追加したい
laravelでログイン機能を実装する時はAuthで実装していることが多いと思います。
そんな中ログインに任意で条件を設けたいときありますよね。
「いや、条件追加すればいいやん」って思う方いると思いますが、これが一筋縄ではいかなかったので今回記事にしようと思いました!
結構使う頻度高そうなので…
今回やりたいこと
ログインに特定の条件のユーザーをログイン出来なくする機能を実装する
条件
laravel 5.2以降・trait AuthenticatesUsersを使用している。
何が問題なの?
今回問題なのは、Authの中のログイン認証(存在確認・ログイン)が1つのメソッドで書かれているため存在確認とログインの処理を別々にしてあげないと任意の条件が追加できない。
下記がログイン周りのソース
namespace App\Http\Controllers\Auth;
class LoginController extends Controller
use AuthenticatesUsers;
public function login(Request $request)
{
$this->validateLogin($request);
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
面倒なのがattemptLogin
メソッド
namespace Illuminate\Foundation\Auth;
trait AuthenticatesUsers
use RedirectsUsers, ThrottlesLogins;
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request),
$request->filled('remember')
);
}
ここがログイン認証を行なっているためこれを分解、再構築してあげないと任意条件を追加できない。(聞いたことあるワードだなぁ〜笑)
分解と再構築
ではログイン処理を分解していきます。
ユーザー情報の取得までは既存処理でその先から変えていきます。
- 所得した情報がテーブルの中にあり、パスワードが一致しているかの判定
- 追加する条件の処理
- ログイン認証
の通りに組んでいきます。
public function login(Request $request)
{
$this->validateLogin($request);
// 失敗回数のチェック
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$canLogin = false; // ログインできるかどうかの判定
$user = User::where('email', $request->email)->first();
// ユーザーの存在確認
if ($user && Hash::check($request->password, $user->password)) {
// 任意条件
if (条件式) {
$canLogin = true;
}
}
// ログイン処理
if ($canLogin === true) {
// ログイン認証
Auth::Guard()->login($user);
if ($request->hasSession()) {
$request->session()->put('auth.password_confirmed_at', time());
}
return $this->sendLoginResponse($request);
}
// 失敗回数の加算処理
$this->incrementLoginAttempts($request);
// 失敗のレスポンス処理
return $this->sendFailedLoginResponse($request);
}
こんな感じで分けて処理して間に追加したい条件を入れてあげればいけます!
まとめ
Authクラスを利用したログイン機能で、こちら側から条件を追加しようとすると処理を分けて自分で書く必要があります。
フレームワークは便利ですが逸脱いた処理は自分で加えないといけないです。それでも今回はあまり修正しなくてよかった例かなと思います。
自分の認識等違えば指摘していただけると幸いです。