172
169

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravelのmiddleware authを理解したい

Last updated at Posted at 2016-04-25

環境

Laravel 5.2
PHP 7.0
ubuntu14.04

目的

Laravelのmiddlewareのauthを理解する
※middlewareのauthは、ログイン状態のチェックを行うもので、ログイン処理ではないので注意
※ログイン処理は、Illuminate\Foundation\AuthのAuthenticatesUsersを調査すべし

調査

  • middlewareの使い方は、route.phpにRoute::groupで指定する
route.php
  Route::group(['middleware' => ['auth']], function () {
        // この中はログインされている場合のみルーティングされる
        Route::get('/', function () {
            return view('dashboad');
	});
  });
  • Http/Kernel.phpにて「auth」というaliasを登録している
Http/Kernel.php
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,

\App\Http\Middleware\Authenticateでやってること

  • handleが定義されている(middlewareはこのhandleメソッドが呼ばれる)
  • 認証は、Auth::guard($guard)->guest()が行っているようだ。
  • 認証NGならログインへリダイレクトしている
  • 認証OKならreturn $next($request);
    • $nextは、本来のrouteが設定される(たとえば/とか)と理解。

前半 (Auth::guard($guard)->guest()Auth::guard()部分)

Auth::guard($guard)がやってること

  • ソースファイル:vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php
\Illuminate\Auth\AuthManager.php
    /**
     * Attempt to get the guard from the local cache.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     */
    public function guard($name = null)
    {
        $name = $name ?: $this->getDefaultDriver();

        return isset($this->guards[$name])
                    ? $this->guards[$name]
                    : $this->guards[$name] = $this->resolve($name);
    }
  • $nameがnullの場合、getDefaultDriver()がコールされ、configのauth.defaults.guardの値(デフォルトは'web')がセットされる
  • return値は三項演算子で求められる
  • $this->guards['web']のissset()がfalseの場合、$this->resolve($name)を実行する
  • $this->resolve($name)取得した$gurad(↓resolveを参照)を返す。

resolve($name)がやってること

  • まず、configのauth.guards.{$name}の値。すなわち、→ auth.guards.webの値を取得する
    • デフォルト:auth.guards.web = ['driver'=>'session','provider'=>'user']
  • 'create'.ucfirst($config['driver']).'Driver';でdriverMethodを生成。
  • driverは「session」なので、 createSessionDriver()となる
  • createSessionDriver()メソッドの実行し、返り値をreturn

createSessionDriver()がやってること

  • createSessionDriver()はAuthManagerクラスにある
  • createUserProvider()を呼び出し、Provider情報を取得(↓createUserProvider参照)
  • SessionGuard()をnew(↓)
    • $guard = new SessionGuard($name, $provider, $this->app['session.store']);
  • $guradにIlluminate\Cookie\CookieJar(暗号化用クッキーの設定?)をセット
  • $guradにIlluminate\Events\Dispatcher(イベントのListen情報)をセット
  • $guradにIlluminate\Http\Request(リクエストパラメータ)をセット
  • $guradを返す。
  • つまり、前半(Auth::guard()部分)では、SessionGuardクラスのオブジェクト取得が目的

createUserProvider()がやってること

  • configのauth.providers.{$provider}の値 → auth.providers.usersの値を取得する
    • デフォルト:auth.providers.users = ['driver'=>'eloquent','model'=>'App\User']
  • 「何を使って、どこからUser情報を取得するか」というのを取得する。
  • デフォルトでは、「eloquentを使って、App\Userモデルの情報をとる」ということ

new SessionGuard()でやっていること

  • ソースファイル:Illuminate\Auth\SessionGurad.php
SessionGurad.php
    public function __construct($name,
                                UserProvider $provider,
                                SessionInterface $session,
                                Request $request = null)
    {
        $this->name = $name;
        $this->session = $session;
        $this->request = $request;
        $this->provider = $provider;
    }
  • セッションやリクエストのセットを行っている

後半 (Auth::guard($guard)->guest()->guest()部分)

guest()はどこにあるか?

  • Auth::guard()にて、SessionGuardクラスのオブジェクトが返ってきているので、SessionGuardクラスのguest()を見てみる
  • しかし、Illuminate\Auth\SessionGuard.phpにはguest()がない
  • use GuardHelpers;を行い、GuardHelpersクラスをトレイトしている
  • Illuminate\Auth\GuardHelpers.phpにguest()がある

guest()がやっていること

  • ソースファイル:Illuminate\Auth\GuardHelpers.php
  • $this->check()を呼び出し
  • $this->check()は、Illuminate\Auth\SessionGuard.phpの$this->user()を呼び出し
GuardHelpers.php
    public function guest()
    {
        return ! $this->check();
    }
GuardHelpers.php
    public function check()
    {
        return ! is_null($this->user());
    }
  • $this->user()はGuardHelperではなく、SessionGuardにある(戻った…)
  • $this->user()の結果がnullだと、check()はfalse、guest()はtrueを返す
    • guest() == true:ログインしていないということ

SessionGuardのuser()がやっていること

  • ソースファイル:Illuminate\Auth\SessionGuard.php
  • $this->loggedOut変数をチェック。Logoutされていればtrueが設定される
    • ログアウトしてもセッションが残っているとかの予防?
  • $idがsessionに保存されているかチェック
$id = $this->session->get($this->getName());
  • Sessionに$idがあれば、Usersテーブルを検索し、ログイン中ユーザーを返す
if (! is_null($id)) {
   $user = $this->provider->retrieveById($id);
}
  • remenber meが有効かチェック
  • $this->getRecaller()でクッキーに保存されているトークンを取得
protected function getRecaller()
{
    return $this->request->cookies->get($this->getRecallerName());
}
  • $this->getUserByRecaller()でUsersテーブルを検索

    • トークンは、remenber meを有効にするとログイン時にUsersテーブルに保存される
  • Sesssion、もしくはRecallerで$userがあればログインユーザーを返す

  • ログインユーザーがいない場合、nullが返る(ログインしていないとなる)

172
169
0

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
172
169

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?