检查哪个“守卫”已登录

42

我有一个使用laravel 5.2开发的多身份认证应用,在config/auth.php中定义了以下守卫:

...
'admin' => [
    'driver' => 'session',
    'provider' => 'admin',
],
'user' => [
    'driver' => 'session',
    'provider' => 'user',
],
...

所以,adminuser

问题出现在视图层,因为这两个已登录的保卫共享一些视图,例如:

Hello {{Auth::guard('admin')->user()->name}}
在这种情况下,守卫被硬编码到视图中,始终为admin(当登录守卫为user时会出错)。为了避免必须再为这个小改变做一个相同的视图,我希望它是动态的,类似于:
在这种情况下,守卫被硬编码到视图中,始终为admin(当登录守卫为user时会出错)。为了避免必须再为这个小改变做一个相同的视图,我希望它能够动态设置,类似于:
Hello {{Auth::guard(<LOGGEDIN GUARD>)->user()->name}}

PS:我知道可以通过获取相应的URL段来实现,例如:www.site.com/pt/user/dasboard,在这种情况下它将是第二个片段,但这样做程序将失去可扩展性,因为将来相应的片段可能不同(如上例中的2)。


请查看这里,了解getGuard()在Laravel的auth区域中是如何实现的。相信这会让你朝着正确的方向前进。 - camelCase
谢谢回复,不幸的是 Auth::guard($this->getGuard()) 触发了 Method [getGuard] does not exist. 的错误。我猜这是一个5.1版本的特性,我也查看了https://dev59.com/tpTfa4cB1Zd3GeqPQ3Ta ,结果相同。 - Miguel
由于您不在auth类中,且该方法为“protected”,因此您无法使用$this来访问它。但是您可以尝试使用类似Auth::guard(Auth::getGuard())的方式来访问它,但我不能确定。 - camelCase
也没有起作用,...class 'Illuminate\Auth\SessionGuard' 没有 'getGuard' 方法 - Miguel
8个回答

73

有一种方法是在IoC容器中扩展Laravel身份验证类,例如,添加一个name()方法来检查当前会话使用哪个守卫,并在该守卫实例上调用user()

另一种方法是在您的Blade模板中简单地使用if语句

@if(Auth::guard('admin')->check())
    Hello {{Auth::guard('admin')->user()->name}}
@elseif(Auth::guard('user')->check())
    Hello {{Auth::guard('user')->user()->name}}
@endif

然而,这有点不太整洁。你可以通过使用partial或者将守卫名称的变量直接从控制器传递到视图,或通过ViewComposer传递到视图,然后执行以下操作来使其更加整洁:

Hello {{Auth::guard($guardName)->user()->name}}

在你的视角中。

在我看来,扩展Laravel的身份验证是最好的选择。


谢谢,但这也会使应用程序失去可扩展性,因为我将被固定在admin/user保护中。 - Miguel
1
非常正确。这就是为什么在这里扩展Laravel身份验证是更好的选择。 - tomfrio
1
@tomfrio 如果你同时登录了两个账户怎么办? - adam78
返回我:auth guard [user] 未定义...但是[admin]可以工作,并且对于非管理员的新用户返回false。 - saber tabatabaee yazdi

14

这将获取用于当前已登录用户的警卫名称。

Auth::getDefaultDriver()

当您登录时,默认情况下会为您获取:

'web'

根据您登录的守卫,可靠性将为您获取该守卫名称。

对于API不适用!!!因为Laravel中默认不使用会话。


2
Auth::getDefaultDriver() 是获取 $this->app['config']['auth.defaults.guard'];它应该始终是配置值。 - Shiro
2
如果您有多个并且动态使用,那么就不是这样了...使用^符号,您将获得在config.auth文件中硬编码的默认值。 - lewis4u
2
这是配置文件中的默认驱动程序,而不是当前登录用户使用的驱动程序。 - Mladen Janjetovic

11

自 Laravel 5.5 起,使用 @auth 模板指令很容易实现。

@auth("user")
    You're a user!
@endauth

@auth("admin")
    You're an administrator!
@endauth

@guest
    You're not logged in!
@endguest

参考资料: https://laravel.com/docs/5.6/blade#if-statements


1
我尝试使用您的答案,但是当我使用auth('admin')登录时,它显示管理员的内容,但仍然显示访客的内容,我不知道为什么?! - The Manh Nguyen

8
在新版本的Laravel中使用:
Auth::getDefaultDriver()

我建议使用全局助手函数,如:
function activeGuard(){

foreach(array_keys(config('auth.guards')) as $guard){

    if(auth()->guard($guard)->check()) return $guard;

}
return null;
}

4

根据Harat的回答,我建立了一个名为CustomAuth的类,并使我能够轻松访问Auth facade方法:user()id()

<?php

namespace App\Utils;

use Illuminate\Support\Facades\Auth;

class CustomAuth{
    static public function user(){
        return Auth::guard(static::activeGuard())->user() ?: null;
    }

    static public function id(){
        return static::user()->MID ?: null;
    }

    static private function activeGuard(){

        foreach(array_keys(config('auth.guards')) as $guard){

            if(auth()->guard($guard)->check()) return $guard;

        }
        return null;
    }
}


1
在我的情况下,我有一个正在运行的项目,其中过于频繁地使用了auth()->user(),因此我被迫找到一种方法,在整个应用程序中继续使用多个守卫。
使用中间件来处理覆盖默认守卫的值。
kernel.php中的web组中添加自定义Web中间件。
protected $middlewareGroups = [
        'web' => [
            .....
            //This cool guy here
            \App\Http\Middleware\CustomWebMiddleware::class,
        ],

使用 CustomWebMiddleware.php 内容:
<?php

namespace App\Http\Middleware;


use Closure;

class CustomWebMiddleware
{

    public function handle($request, Closure $next)
    {
        $customGuard = 'custom-guard-name-goes-here';
        if (auth($customGuard)->check()) {
            config()->set('auth.defaults.guard', $customGuard);
        }

        // if you have multiple guards you may use this foreach to ease your work.
        /*$guards = config('auth.guards');
        foreach ($guards as $guardName => $guard) {
            if ($guard['driver'] == 'session' && auth($guardName)->check()) {
                config()->set('auth.defaults.guard', $guardName);
            }
        }*/

        return $next($request);
    }


}


1

使用auth()->guard($guard)->getName()会返回两种不同类型的值

如果是管理员守卫,则返回login_admin_59ba36addc2b2f9401580f014c7f58ea4e30989d

如果是Web守卫或根据您的用例是用户守卫,则返回login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d。因此,您可以针对此进行测试。

因此,一个简单的用例可以如下所述:

 if(str_contains(auth()->guard($guard)->getName(), 'admin')){
      dd('is admin');
   }

如果是管理员,将显示'is admin',否则将显示默认值


0
Auth::getDefaultDriver()

上面将返回当前的守卫,对于你来说是(用户或管理员)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接