Laravel 5.2 multi auth について


実装に関するチュートリ的なコードはこちらにまとまっている。

http://qiita.com/zaburo/items/cd3f2ccfb5c2d0fba340

一口にMultiAuthといっても、単純ではない

- 認証に関するモデル周りのストレージ機構
- コントローラ
- ミドルウェア

この辺りをうまいこと綺麗に分離してやる必要がある。

通常のauthを利用する場合、`make:auth`でスケルトンを作成する事になるが、
MultiAuth使用時にコレを援用するのは難しそう。
(管理画面に一般公開のregisterは不要だったりとか…)

## ストレージ機構の用意

ストレージ周りのauth処理をコントロールする際には、`config/auth.php`に設定を追加する。

````
<?php

return [

    'guards' => [
        // 追加
        'admin' => [
            'driver' => 'session',
            'provider' => 'admin',
        ],
    ],
    'providers' => [ 
        // 追加
        'admin' => [
            'driver' => 'eloquent',
            'model' => \Admin\Models\AdminUser::class,
        ],
    ],
];
````

例えば管理画面用の認証機構を追加するには、admin providerを追加し、admin provider を利用する admin gurardsを追加する。

guard : 認証に関するIF周りの機構
provider : 実際の認証処理を行うロジック

みたいな感じ。とりあえずproviderはEloquentを利用するのが良さそう。

AdminUserクラスの中身はこんな感じになる。

````
<?php
namespace Admin\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{

    protected $table = "t_admins";

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

}
````

`Illuminate\Foundation\Auth\User`という形で認証利用可能なEloquent の雛形が用意されているのでそれを使うのが楽そう。

これの中身は,

````
<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;
}
````

みたいな感じになっているので、Modelを継承しながらこの辺のインターフェイス、トレイト自分で引っ張ってきても良い。

## コントローラ周りの処理

Providerの設定が終わってカスタムGuardが使用可能になったらController層の設定を行う。

標準認証では、`Rout::auth()`が使用可能だったため、この中身を触れば簡単に認証を通せたけど、管理画面とかのニーズを考えるとコレが常に有効ってわけでもない。

ココは自分で`AuthController`を作成して、自分でルートを定義するのがてっとり早そう。

自分で設定すると言っても基本はコピペでOK。 `Route::auth()`の中身はこんな感じになってる。

````
public function auth()
{
    // Authentication Routes...
    $this->get('login', 'Auth\AuthController@showLoginForm');
    $this->post('login', 'Auth\AuthController@login');
    $this->get('logout', 'Auth\AuthController@logout');

    // Registration Routes...
    $this->get('register', 'Auth\AuthController@showRegistrationForm');
    $this->post('register', 'Auth\AuthController@register');

    // Password Reset Routes...
    $this->get('password/reset/{token?}', 'Auth\PasswordController@showResetForm');
    $this->post('password/email', 'Auth\PasswordController@sendResetLinkEmail');
    $this->post('password/reset', 'Auth\PasswordController@reset');
}
````

自分の名前空間に`AuthController`をコピペで持ってきて配置して、以下の用にルートを生やしてやると楽っぽい。

````
// 管理画面 Route
Route::group([
    'middleware' => ['web'],
    "namespace" => "Admin\\Http\\Controllers",
    "prefix" => "/admin/"
], function () {
    // 比津町な分だけ。今回はログイン・ログアウトのみで、registerはartisan対応…など
    Route::get('login', 'Auth\AuthController@showLoginForm');
    Route::post('login', 'Auth\AuthController@login');
    Route::get('logout', 'Auth\AuthController@logout');
});
````

`prefix`と`namespace`をうまいこと利用すると、`Route:auth()`のコピペがうまいこと機能してくれる。

### AuthController の拡張

Multiで運用する時、Controllerのパラメータも色々と修正する必要がありそう。

$redirectTo: Admin用のログイン後画面に切り替え
$redirectAfterLogout: Admin用のログアウト後画面に切り替え
$guard: 使用するGuardの名前。admin
$loginView: ログイン画面で使用するViewファイル名(view関数の引数相当)
$registerView: 登録画面で使用するViewファイル名(view関数の引数相当)
validator(): registerを使用するなら。Admin用のモデルに切り替え 
create(): registerを使用するなら。Admin用のモデルに切り替え

もうちょっと楽になりたいものです(助かってますが)。



## 認証の実行・ミドルウェア

このようにしてログイン・ログアウトの機構を用意すれば、後は認証先の画面を用意するだけ。

ミドルウェア`auth`はデフォルトのgurard運用になるので、
例えばadmin guardでミドルウェアを書けるなら`auth:admin`とする。

Authクラスから認証中ユーザを取ってくる際にも `Auth::guard("admin")->user()`みたいにしてやればいい。