環境
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
:ログインしていないということ
- guest() ==
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が返る(ログインしていないとなる)