PHP Laravel5.2でmulti-auth(複数テーブルでの認証)を実装

2016/04/11

Laravel5.2でマルチ認証

概要

LaravelとはPHPの中で今最も伸びているフレームワークです。
処理速度が遅いなどありますが、かなり使い安く拡張性が高いと思っています。

今回は、Larabel5.2から対応されたMultiAuthを紹介します。
MultiAuthなので、複数の認証です。

今回は、一般ユーザー(users)・管理ユーザー(admins)の2つテーブルを使用した認証処理を実装します。

まずはプロジェクト作成


$ composer create-project laravel/laravel project --prefer-dist

これでプロジェクトが生成されました。
.env にDB接続情報を設定した後、cdします。


$ cd project

通常の認証を実装

一般ユーザー用の認証を作成します。
まずは画面等を生成。


$ php artisan make:auth

次にテーブルを生成


$ php artisan migrate

これで migrations、password_resets、usersテーブルが作成されました。

管理ユーザー用の認証

モデルを生成します。


$ php artisan make:model Admin

app/User.php と同じにする


namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    //
}

adminsテーブルを生成


$ php artisan make:migration create_admin_table

こちらもusersテーブルに合わせる
database/migrate/xxxxxxx_create_admin_table.php


use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateAdminTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('admins');
    }
}

users,adminsテーブルの初期データを設定するseederを作成


$ php artisan make:seeder UserTableSeeder
$ php artisan make:seeder AdminTableSeeder

database/seeds/UserTableSeeder.php


use Illuminate\Database\Seeder;

class UserTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->truncate();

        DB::table('users')->insert([
            'name' => 'ユーザー',
            'email' => 'user@example.com',
            'password' => bcrypt('password'),
        ]);
    }
}

database/seeds/AdminTableSeeder.php


use Illuminate\Database\Seeder;

class AdminTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('admins')->truncate();

        DB::table('admins')->insert([
            'name' => '管理者',
            'email' => 'admin@example.com',
            'password' => bcrypt('password'),
        ]);
    }
}

DatabaseSeeder.php に登録


use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UserTableSeeder::class);
        $this->call(AdminTableSeeder::class);
    }
}

migration,seedを実行


$ php artisan migrate:refresh --seed

ドライバーの設定
config/auth.phpを変更


return [

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],

        //追加
        'user' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        //追加 for admin
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
    ],

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

        //追加 for admin
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class,
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],

        //追加 for admin
        'admin' => [
            'provider' => 'admins',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],
];

ルートを設定
app/Http/routes.php


Route::group(['middleware' => ['web']], function () {
    // admin
    Route::group(['middleware' => 'guest:admin'], function () {
        Route::get('/admin/login','AdminAuthController@showLoginForm');
        Route::post('/admin/login','AdminAuthController@login');
    });

    Route::group(['middleware' => 'auth:admin'], function () {
        Route::get('/admin', 'AdminHomeController@index');
        Route::get('/admin/home','AdminHomeController@index');
    });

    Route::get('/admin/logout','AdminAuthController@logout');

    // user
    Route::auth();

    Route::get('/home', 'HomeController@index');
});

usersの方は、すでに用意されている「Route::auth();」を設定し、adminsにログイン・ログアウトなどを追加しています。

次にミドルウェアを少し変更します。
「// add admin」のif分が追加したヵ所です。
app/Http/Middleware/Authenticate.php


public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->guest()) {
        if ($request->ajax()) {
            return response('Unauthorized.', 401);
        } else {
            // add admin
            if($guard == 'admin'){
                return redirect()->guest('/admin/login');
            }
            return redirect()->guest('login');
        }
    }

    return $next($request);
}

app/Http/Middleware/RedirectIfAuthenticated.php


public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        // add admin
        if($guard == 'admin'){
            return redirect('/admin/home/');
        }
        return redirect('/');
    }

    return $next($request);
}

最後にcontroller,viewを作成します。


php artisan make:controller AdminAuthController

app/Http/Controllers/AdminAuthController.php

<?php

namespace App\Http\Controllers;

use App\Admin;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

class AdminAuthController extends Controller
{
    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    protected $guard = 'admin';
    protected $redirectTo = '/admin/home';
    protected $loginView = 'admin.login';


    /**
     * Create a new authentication controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:admin', ['except' => 'logout']);
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:admins',
            'password' => 'required|confirmed|min:6',
        ]);
    }

    public function showLoginForm()
    {
        if (view()->exists('admin.authenticate')) {
            return view('admin.authenticate');
        }

        return view('admin.login');
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return Admin
     */
    protected function create(array $data)
    {
        return Admin::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}

php artisan make:controller AdminHomeController

app/Http/Controllers/AdminHomeController.php は、既存のHomeControllerの中身をコピーし、クラス名・パスなどを修正してください。

viewの作成
resources/views/ 内にadminディレクトリを作成し、以下のviewファイルをまるごとコピーしてきます。

・resources/views/home.blade.php
・resources/views/auth/login.blade.php

loginの方は、formのパスを「url('/admin/login')」に変更

以上で完了です。
/home、/admin/homeのURLへ接続し確認してください。

Related

Vagrant+Docker+PHP環境で「session.save_path」指定時に、セッションファイルが空になるエラー

ファイル共有でのフォルダの所有者を設定 結論 PHP5.4.28 からセッションファイルのownerはrootもしくはWebサーバのユーザに限るという制限が...

LINEと連携したテイクアウト事前注文システム徹底比較!

目次 テイクアウト予約・注文受付システムのトレンド LINEと連携したテイクアウト事前注文システムの価格表 L.B.B.Cloud テイクイーツ ...

PHPで動画の撮影日を取得

PHPで動画の撮影日を取得 概要 PHPからffprobeコマンドを実行し、動画の撮影日時を取得します。 コード $posted_at = ...

FullCalendarでGoogleカレンダーのようなUIを実装

jQueryプラグインFullCalendarのサンプル 概要 FullCalendarを使用して、GoogleカレンダーのようなUIを実装する使用例を...

PHP 正規表現でIPアドレス形式の文字列か判定

正規表現でIPアドレスの入力チェック 概要 フォームで入力されたIPアドレスが正当な文字列か判定するためのバリデーション処理を実装します。 基本的...

rbenv環境でRuby on Railsのアプリケーションを一瞬で自動生成

アプリケーション構築時に最初に行う手順 概要 アプリケーションを作成するまでの手順を記載しています。 rbenvなどの環境が設定済と仮定して話を進めま...
トップへ戻る