「PHPフレームワーク Laravel Webアプリケーション開発」の感想・備忘録8

スポンサーリンク

認証

認証を支えるクラス

以下の3つのインターフェースとそれらを実装したクラスが用意されている。

  • Illuminate\Contracts\Auth\Factory
    認証方法を決めるためのインターフェース。
    デフォルトでは具象クラスIlluminate/Auth/AuthManagerが用意されている。
    Illuminate\Auth\Middleware\Authenticateで使われていて、config/auth.phpの設定値を取得している。
  • Illuminate\Contracts\Auth\Guard
    認証情報へアクセスするためのメソッドを提供するインターフェース。
    デフォルトでは具象クラスIlluminate\Auth\SessionGuardとIlluminate\Auth\TokenGuardが用意されている。 Illuminate\Contracts\Auth\UserProviderのメソッドを使って認証情報を取得している。
  • Illuminate\Contracts\Auth\UserProvider
    認証処理を行うメソッドを提供するインターフェース。
    デフォルトでは具象クラスIlluminate\Auth\EloquentUserProviderとIlluminate\Auth\DatabaseUserProviderが用意されている。

認証を支えるメソッド

Illuminate\Contracts\Auth\UserProviderインターフェースで定義されているメソッド。

  • retrieveById
    セッションに保存されたユニーク値(ユーザーIDなど)からユーザー情報を取得する。
  • retrieveByToken
    クッキーのトークンからユーザー情報を取得する。(クッキーによる自動ログイン)
  • updateRememberToken
    retrieveByTokenメソッドで利用するトークンを更新する。
  • retrieveByCredentials
    ログインを行うattemptメソッドが内部でコールするメソッド。
    指定された配列からユーザー情報を取得する。
  • validateCredentials
    attemptメソッドで指定された配列の検証を行う。(パスワードのハッシュ値の比較など)

上記のメソッドの引数または戻り値はIlluminate\Contracts\Auth\Authenticatableインターフェースを実装したクラスである。

Illuminate\Contracts\Auth\Authenticatableインターフェースで定義されているメソッド。

認証処理でユーザー情報へアクセスする際に利用されている。

  • getAuthIdentifierName
    ユーザーを特定するための識別子名を返す。
    通常はデータベースのカラム名。
  • getAuthIdentifier
    ユーザー特定が可能な値を返す。
    getAuthIdentifierNameメソッドで取得した値を使って配列などから取り出す。
  • getAuthPassword
    パスワードを返す。
  • getRememberToken
    自動ログインで利用するトークンの値を返す。
  • setRememberToken
    自動ログインで利用するトークンの値をセットする。
  • getRememberTokenName
    自動ログインで利用するトークンの名前を返す。

データベースとセッションによる認証

デフォルトでは、Illuminate\Contracts\Auth\Authenticatableインターフェースを実装したIlluminate\Auth\GenericUser、およびセッション情報を元に認証情報へアクセスするためのIlluminate\Auth\SessionGuardをそのまま利用することができる。
※ Illuminate\Auth\GenericUserはデフォルトのuserテーブルに対応している。

config/auth.phpに利用するguardとproviderを設定する。

  • guardのdriverはsessionまたはtokenを指定可能。
  • providerのdriverにはeloquentまたはdatabaseを指定可能。
    databaseの場合はQueryBuilderが利用される。
  • eloquentの場合はmodelでeloquentクラスのフルパス、databaseの場合はtableでテーブル名、を指定する。

認可

2種類ある。

  • Gate: 1つの認可処理に名前を付ける。
  • Policy: 複数の認可処理を記述する。

どちらもApp\Provider\AuthServiceProviderに記述して利用する。

Gate

1. app/Providers/AuthServiceProviderに認可を定義。

use Illuminate\Contracts\Auth\Access\Gate;
// 〜省略〜
public function boot(Gate $gate)
{
    $this->registerPolicies();

    $gate->define('user-access', function(\App\User $user, $id) {
        return intval($user->getAuthIdentifier()) === intval($id);
    });
}
  • defineメソッドの第2引数のクロージャは、第1引数でIlluminate\Contracts\Auth\Authenticatableインターフェースの具象クラスのインスタンスを利用する事ができる。
  • $gate->before(function(\App\User $user, $id){ // 処理 });で認可の前に実行したい処理を定義することができる。ログ出力などに使う。

これをコントローラ、ミドルウェア、テンプレートなどで利用する。

2. 認可の適用 (コントローラの場合)

use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Auth\Access\Gate;
// 〜省略〜
private $authManager;
private $gate;

public function __construct(AuthManager $authManager, Gate $gate)
{
    $this->authManager = $authManager;
    $this->gate = $gate;
}
public function __invoke(string $id)
{
    if ($this->gate->allows('user-access', $id)) {
        // 認可されている場合の処理
    }
}
  • allowsではなくdeniesメソッドにすると、認可されていない場合に実行される。

Policy

認可処理をまとめて記述する仕組み。

1. ポリシークラスの生成

php artisan make:policy XxxPolicy

モデルを指定する場合は、--model=Xxxを付ける。
(モデルを引数で受け取るメソッドも同時に生成される)
php artisan make:policy BookPolicy --model=Book

2. ポリシークラスの登録

App\Providers\AuthServiceProviderの$policies配列に追加する。
キーにモデル、値にポリシークラスのフルパスを指定する。

protected $policies = [
    'App\Book' => 'App\Policies\BookPolicy',
];

3. 認可の適用

canメソッド
$user =\Auth::user();
if ($user->can('view', $book)) {
    echo '認可されています。(can)<br>';
} else {
    echo '認可されていません。(can)<br>';
}
authorizeメソッド
$this->authorize('view', $book);
echo '認可されています。';
bladeでの認可の適用

@can〜@canelse〜@endcanディレクティブを使用する。

@can('view', $book)
{{-- viewが認可されている場合 --}}
@elsecan('create', \App\Book)
{{-- createが認可されている場合 --}}
@endcan

コメント