BETA

Laravelの認証済チェックの流れ

投稿日:2018-10-23
最終更新:2018-10-24
※この記事は外部サイト(http://syogo0417.hatenablog.com/entry/2018...)からのクロス投稿です

はじめに

remember meを使った認証をする場合、Eloquentのモデルにremember_tokenカラムを生やしてトークンを覚えさせますが、
このカラムを使わずにremember meできるのか、調べたら副次的に認証済チェックの流れのコードを読むことになったので、
備忘録としてメモしておきます。

もともとの目的だったremember_tokenカラムを使わずにremember meできるのか?についての結論は、
「できない」が回答となります。

認証済チェックしてるコード

Illuminate\Auth\SessionGuard::user()

checkメソッドも結局上記メソッドの戻り値がnullかどうかしかチェックしていないのでコレ使って残しときます。 (間違ってる箇所あったら教えてください)

    public function user()
    {
        if ($this->loggedOut) { // -- 1
            return;
        }

        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        $id = $this->session->get($this->getName()); // -- 2

        // First we will try to load the user using the identifier in the session if
        // one exists. Otherwise we will check for a "remember me" cookie in this
        // request, and if one exists, attempt to retrieve the user using that.
        if (! is_null($id)) {
            if ($this->user = $this->provider->retrieveById($id)) {
                $this->fireAuthenticatedEvent($this->user);
            }
        }

        // If the user is null, but we decrypt a "recaller" cookie we can attempt to
        // pull the user data on that cookie which serves as a remember cookie on
        // the application. Once we have a user we can return it to the caller.
        $recaller = $this->recaller(); // -- 3

        if (is_null($this->user) && ! is_null($recaller)) {
            $this->user = $this->userFromRecaller($recaller); // -- 4

            if ($this->user) {
                $this->updateSession($this->user->getAuthIdentifier());

                $this->fireLoginEvent($this->user, true);
            }
        }

        return $this->user;
    }

上記コードに // -- 番号で書いた箇所について書いていきます。

認証済チェックの流れ

  1. ログアウトのチェック
    これはauth()->logout()するとフラグがtrueになるので、ログアウトを実行したかどうかをチェックしてます。

  2. ブラウザセッションにデータが残っているかをチェック
    $this->getName()では、
    「login_ + guard名 + _ + 認証で使っているEloquentクラスのSHA-1」の文字列で、
    セッションからデータを取ってます。値は認証情報に使ってるEloquentのIDが取れる。

    IDが取れればDB上から該当ユーザーのレコード取ってきて、あればログイン済となる。
    DBを毎回見ては居るので、ユーザーが削除されてれば、ここで$this->userは必ずnullになるので未認証扱いになる。

  3. cookieからRecallerを作る
    これは、remember_tokenに設定したトークン文字列がcookieに含まれてるので、それを取ってます。

  4. トークンを使って、認証ユーザーの情報を取る
    3.で取ったトークン文字列を使って、remember_tokenで充てにいく。

まとめ

セッションが残っている間は、そこからDBにユーザーを取りに行き、

セッションが消えた場合は、cookieにremember_tokenの文字列が入っているので、
この文字列を使ってトークン認証する。

その他

remember_token生成に使ってる、Illuminate\Support\Str::randomってどこまで一意性担保できてるのか気になった。
phpdocには「Generate a more truly "random" alpha-numeric string.」って書いてあるけど・・・。
※remember_tokenではlengthを60に指定して生成してる

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@64MeSrzaJWde0W4zの技術ブログ

よく一緒に読まれる記事

3件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
10/24 04:13

PHP7調査(31)暗号論的に安全な疑似乱数生成器(CSRPNG)を提供する新関数 - Qiita

実装に random_bytes 使ってるので大丈夫だと思います!

10/24 08:59

そうなんですね! 教えてくださり、ありがとうございます!

10/24 09:00

ボタン押せてる感がないから連打してもうた・・・(そして消せない・・・?)

目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!