ログインに条件を追加する

ログイン可能なユーザーを制限するときにどこいじると楽かの試行錯誤と結果。

やりたいこと

  • 有効なユーザかつ有効な所属企業の場合ログイン可能
  • Authの標準機能PWリセットが上記ユーザーの場合のみ利用可能

試したこと

  1. ログインコントローラーを改造する ⇒ PWリセットは別途対応が必要に(めんどい)
  2. ログイン可能ユーザーのEloquentモデルを別に定義する ⇒ Auth全般が適用範囲になるので楽

ログインコントローラーを改造する

調べると色々出てくる方法なので簡単に。 ログイン試行する attemptLogin や認証情報を返す credentials あたりをいじればよい。

class LoginController extends Controller
    ...
    protected function attemptLogin(Request $request)
    {
        $user = User::with('company')->valid()->where('email', $request->input('email'))->first();
        if (is_null($user)) {
            return false;
        }
        if ($user->company->isInvalid()) {
            return false;
        }
        return $this->guard()->attempt(
            $this->credentials($request), $request->filled('remember')
        );
    }
    ...

スマートじゃないが意図した動作をする。 PWリセットも同じようにやればできるはず(めんどい)

ログイン可能ユーザーのEloquentモデルを別に定義する

Userを継承した ValidUser を定義。これのグローバルスコープに追加条件を設定する。 テーブル名を明示しないとvalid_usersテーブルを探してしまうので注意。

class ValidUser extends User
{
    protected $table = 'users';

    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('valid_user', function (Builder $builder) {
            $builder->where('status', 1)
                ->whereExists(function ($query) {
                    $query->select(DB::raw(1))
                        ->from('companies')
                        ->whereRaw('companies.id = users.company_id')
                        ->where('status', 1);
                });
        });
    }
}

この子をconfig/auth.phpで指定してあげれば完了。

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Eloquents\ValidUser::class,
        ],
    ],

動作確認

f:id:ichi_404:20190718110806p:plain

心地よいシンプルさ。