LoginSignup
13
27

More than 5 years have passed since last update.

Laravel 5.4 のログイン認証で複数テーブルを使う

Last updated at Posted at 2017-02-15

果たしてこれでいいのかという疑問と、作業ログを兼ねて。Laravel をよくわかっていないので、変なことしてるかも。指摘お待ちしています。

実現したいこと

  • 1つのログイン画面で、複数テーブルを使った認証を行う
    • User テーブルと, Admin テーブルがあって、どちらかにあればログインできて、それぞれの画面に遷移する、みたいな。
    • その上 User テーブルと Admin テーブルで認証に使用するカラムが異なる
    • User テーブルが id
    • Admin テーブルが username

標準の make:auth は使えないのかなーと思っているので、自分で作っていく。

環境

  • macOS 10.12.3
  • PHP 7.0
  • Laravel 5.4
  • MySQL

準備

プロジェクトの作成といろいろ生成

bash
$ composer create-project laravel/laravel multi-auth-sample --prefer-dist "5.4.*"
$ cd multi-auth-sample
$ php artisan make:controller LoginController
$ php artisan make:controller AdminController
$ php artisan make:controller UserController
$ php artisan make:model Admin -m # User は既存のものを使う
$ php artisan make:seeder AdminTableSeeder
$ php artisan make:seeder UserTableSeeder
$ php artisan make:middleware CheckAuthenticate
$ php artisan make:middleware CheckAdminAuthenticate

route ファイル編集

routes/web.php
<?php
// ログイン画面
Route::get('/', 'LoginController@index')->name('login.index');
Route::post('/', 'LoginController@authenticate')->name('login.login');
Route::match(['get', 'post'], 'logout', 'LoginController@logout')->name('login.logout');
// Admin画面
Route::get('admin', 'AdminController@index')->name('admin.index');
// User画面
Route::get('user', 'UserController@index')->name('user.index');

作成

Model

app/Admin.php
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    //
}

Migrations

create_admins_table
public function up()
{
    Schema::create('admins', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();

        $table->string('username')->unique();
        $table->string('password');
        $table->rememberToken();
    });
}

Seeds

database/seeds/AdminTableSeeder.php
public function run()
{
    DB::table('admins')->insert([
        'username' => 'admin',
        'password' => Hash::make('Passw0rd'),
        'remember_token' => '',
        'created_at' => Carbon::now(),
        'updated_at' => Carbon::now(),
    ]);
}
database/seeds/UserTableSeeder.php
public function run()
{
    DB::table('users')->insert([
        'name' => 'user',
        'email' => 'user@example.com',
        'password' => Hash::make('User2017'),
        'remember_token' => '',
        'created_at' => Carbon::now(),
        'updated_at' => Carbon::now(),
    ]);
}
database/seeds/DatabaseSeeder.php
public function run()
{
    $this->call(AdminTableSeeder::class);
    $this->call(UserTableSeeder::class);
}

View

resources/views/login.blade.php
<form action="/" method="post">
    {{csrf_field()}}
    <label>ID: <input type="text" name="id" id="id"></label>
    <label>Password: <input type="password" name="password"> </label>
    <button type="submit">Login</button>
</form>

Middleware

app/Http/Kernel.php
protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    // 追加
    'auth.check.admin' => \App\Http\Middleware\CheckAdminAuthenticate::class,
    'auth.check.user' => \App\Http\Middleware\CheckAuthenticate::class,
    // 追加ここまで
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
config/auth.php
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    // 追加
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
],
'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],
    // 追加
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Admin::class,
    ],
],
'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_resets',
        'expire' => 60,
    ],
    // 追加
    'admins' => [
        'provider' => 'admins',
        'table' => 'password_resets',
        'expire' => 60,
    ],
],
app/Http/Middleware/CheckAuthenticate.php
public function handle($request, Closure $next)
{
    if (Auth::guard('web')->check() === false) {
        return redirect()->route('login.index');
    }
    return $next($request);
}
app/Http/Middleware/CheckAdminAuthenticate.php
public function handle($request, Closure $next)
{
    if (Auth::guard('admin')->check() === false) {
        return redirect()->route('login.index');
    }
    return $next($request);
}

Controller

app/Http/Controllers/LoginController.php
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $username = 'id';

    public function username()
    {
        return $this->username;
    }

    public function index()
    {
        return view('login');
    }

    public function logout(Request $request)
    {
        if (Auth::guard('web')->check()) {
            Auth::guard('web')->logout();
        }
        if (Auth::guard('admin')->check()) {
            Auth::guard('admin')->logout();
        }
        return redirect()->route('login.index');
    }

    public function authenticate(Request $request)
    {
        // User ログイン
        Auth::guard('web');
        $this->validateLogin($request);
        $id = $request->input('id');
        $password = $request->input('password');
        if (Auth::attempt(['id' => $id, 'password' => $password])) {
            return redirect()->route('user.index');
        }

        // Admin ログイン
        Auth::guard('admin');
        $this->username = 'username';
        if (Auth::guard('admin')->attempt(['username' => $id, 'password' => $password])) {
            return redirect()->route('admin.index');
        }

        return redirect()->back();
    }
}
app/Http/Controllers/AdminController.php
class AdminController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth.check.admin');
    }

    public function index()
    {
        return 'AdminPage!';
    }
}
app/Http/Controllers/UserController.php
class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth.check.user');
    }

    public function index()
    {
        return 'UserPage!';
    }
}

確認

bash
$ php artisan migrate --seed
$ php artisan serve
# http://localhost:8000/ へアクセス
13
27
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
27