質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

Laravel の@authについて

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 174

mikeross

score 12

いつもお世話になっております。

前回の質問で回答に倣って公式サイトを読んでみたのですが、分からないことがあるので、こちらでお伺いしたいです。
https://teratail.com/questions/190886

現在Laravelを勉強しており、マルチ認証を実装したいため、
まずは以下のサイトを参考にマルチ認証(user権限とadmin権限)を実装してみました。

Laravel5.7でMulti Authを試す。

前回の質問の内容を検証しているなかで、新しく分からない箇所が出てきました。

それは、

・admin権限でログインをしている際に、サイトのトップページ(localhost:8890)でAuth::guard()->check()を行うとfalseとなるが、adminの管理画面、つまりlocalhost:8890/admin/homeではtrueが返ってくる
・Auth::guard("admin")->check()ではもちろん両方ともtrueが返ってくる

なぜ、同じログイン状態でも開いているページによって、条件分岐の返り値が変わってしまうのでしょうか。

ちなみにauth.phpは以下のようにしております。

<?php
# config/auth.php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    | メモ : https://qiita.com/washio12/items/59f5cde23b4205973c6b
    */

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
            'hash'     => false,
        ],

        'user' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'admin' => [
            'driver'   => 'session',
            'provider' => 'admins',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model'  => App\Models\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model'  => App\Models\Admin::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users'     => [
            'provider' => 'users',
            'table'    => 'password_resets',
            'expire'   => 60,
        ],
        'admins'    => [
            'provider' => 'admins',
            'table'    => 'password_resets',
            'expire'   => 60,
        ],
    ],

];

bladeでは以下のようなじょうけん分岐を行なっております。

@if(Auth::guard()->check())
        adminでログイン中です<br>
@endif

# localhost:8890 ではfalse
# localhost:8890/admin/home ではtrue

ちなみに、デバッグで処理を追っていったところ、

# vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeRoot();

        if (! $instance) {
            throw new RuntimeException('A facade root has not been set.');
        }

        return $instance->$method(...$args);
    }


上記コードのstatic::getFacadeRoot();が始まる前に、
・localhost:8890では、guardsにweb(デフォルト値)が格納され
・localhost:8890/admin/homeではguardsにadminとuser
がそれぞれ配列の形で格納されていました。

一応自分でもソースを追ったり、公式サイトを見るようにして調べてはいるのですが、
まだ知識が浅いため、どの部分で条件分岐(Auth::guard()->check())の値が変わってしまうのかがわかりません。

もともとLaravel自体がそういった仕様であるのか、そもそもどこか見落としているのかすら判断がつきません。

一応下記のようにそれぞれの権限に対して条件分岐をすれば、もんだいはないのですが、

@if(Auth::guard('web')->check())
        <a href="{{ route('logout') }}"><i class="fas fa-chevron-right"></i>ログアウト</a>
@elseif(Auth::guard('admin')->check())
        <a href="{{ route('admin.logout') }}"><i class="fas fa-chevron-right"></i>ログアウト</a>
@endauth

とても見栄えが悪く、user権限、admin権限問わず、ログイン状態であれば、
以下のように条件分岐ができるのが理想です。

@if(Auth::guard()->check())
        <a href="{{ route('logout') }}"><i class="fas fa-chevron-right"></i>ログアウト</a>
@endauth

どなたかわかる方がいらっしゃればご教授お願いいたします。

追記1

@dd(Auth::guard())をした際に、adminでログインしているにも関わらず
・localhost:8890 : SessionGuard が "web" 
・localhost:8890/admin/home : SessionGuard が "admin" 

のようになっているようです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

マルチ認証機能は、扱いが難しいので、前回のkawaxさんがオススメしていたように、
一つの認証設定と、認可機能によって処理分岐できる、ゲート認可機能での管理者ユーザーの実現も検討してみてください。
Laravel 5.8 認可 ポリシーを使ったアクションの認可

以下のHorizonの例のように、メールアドレスを元に真偽判断ができたりします。
Laravel 5.8 Laravel Horizon

Gate::define('viewHorizon', function ($user) {
        return in_array($user->email, [
            'taylor@laravel.com',
        ]);
    });

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る