如何在Laravel Guard上使用主域和子域

时间:2018-06-23 03:10:39

标签: php laravel authentication multi-tenant laravel-session

我正在构建一个多租户应用程序,其构想是管理员通过主域(http://myapp.app)访问仪表板,普通用户访问各自子域({{3})上的另一个仪表板})

为此,我创建了一个使用会话驱动程序的自定义防护(admin)和管理员提供程序,该提供程序是使用高级驱动程序的自定义提供程序和我的表 admins

// config/auth.php

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

   'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
   ],

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


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

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

阅读了很多有关身份验证工作方式的文档后,我收到了带有重置密码系统的管理员仪表板工作事件,但是部分子域仍然存在一些问题

自从我登录用户以来,租户子域上常规用户的登录似乎正在运行,如果我检查了记住选项,这将反映在获取令牌的数据库中 遇到的最重要的问题是,当我尝试使用身份验证功能(外观或注入)来检索用户时,无法获得用户,该方法始终返回null 我尝试为auth对象指定防护,但仍然无法正常工作 当我使用 guard对象时,它有一个成员 user ,它假定包含登录的用户,但始终为null,并且是否要问我为什么需要用户,因为我需要检查用户的权限

我的理论是我的会话仅适用于主域,而不适用于子域,或者我需要指定另一个Cookie,但说实话我只是在猜测

我什至不知道我的代码的哪一部分会有用,但是如果您与此问题相关,欢迎您提供的所有信息,如果您需要更多信息或特定内容,请告诉我我的代码

预先感谢

更新 这是用户控制器的摘录

use Illuminate\Auth\AuthManager as Auth;
use Illuminate\Contracts\Auth\Access\Gate;
use Monica\Http\Controllers\Controller;

class UsersController extends Controller
{
    protected $auth;

    protected $gate;

    public function __construct(Auth $auth, Gate $gate)
    {
        $this->middleware('web');
        $this->auth = $auth;
        $this->gate = $gate;
        $this->auth->guard('web');
        $this->auth->shouldUse('web');
        $u = $this->auth->guard();
        dd($u);
    }
}

这是转储的防护对象:

SessionGuard {#311 ▼
  #name: "admin"
  #lastAttempted: null
  #viaRemember: false
  #session: Store {#294 ▼
    #id: "XIWy7hEJRuX1cL2bBN7pf7DqT54PpbTyYBXPv6He"
    #name: "no_named_app_session"
    #attributes: array:5 [▼
       "_token" => "RrTXOZwj56Nk9OqxkdkLdDztfZb6TeW2knVf5xc7"
       "_previous" => array:1 [▼
       "url" => "http://monica.app/admin/admins"
    ]
      "_flash" => array:2 [▼
        "old" => []
        "new" => []
    ]
      "url" => []
      "login_admin_59ba36addc2b2f9401580f014c7f58ea4e30989d" => "66f4aab0-6566-11e8-b51d-673dcbafed23"
]
  #handler: FileSessionHandler {#295 ▼
    #files: Filesystem {#115}
    #path: "/home/vagrant/Code/PHP/monica/storage/framework/sessions"
    #minutes: "120"
  }
  #started: true
}
  #cookie: CookieJar {#292 ▼
    #path: "/"
    #domain: null
    #secure: false
    #sameSite: null
    #queued: []
  }
  #request: Request {#42 ▶}
  #events: Dispatcher {#26 ▶}
  #loggedOut: false
  #recallAttempted: false
  #user: Admin {#328 ▶}
  #provider: EloquentUserProvider {#308 ▼
    #hasher: BcryptHasher {#310 ▶}
    #model: "Monica\Models\Admin"
  }
 }

2 个答案:

答案 0 :(得分:0)

您可以尝试几种不同的方法来动态设置防护。

1。使用auth()->shouldUse('the_guard')

在中间件或控制器的构造函数中,根据域或主机名将保护程序的名称传递到shouldUse方法中:

if (request()->getHttpHost() === 'myapp.com') {
    auth()->shouldUse('admin');
} else {
    auth()->shouldUse('api'); // use the guard for tenants
}

2。再次在中间件或控制器构造函数中覆盖config/auth.php中的默认配置:

if (request()->getHttpHost() === 'myapp.com') {
    config(['auth.defaults.guard' => 'admin');
} else {
    config(['auth.defaults.guard' => 'api'); // use the guard for tenants
}

如果您使用自定义逻辑登录,请确保使用Authenticable方法之一设置auth模型:登录,一次,尝试等。

我在具有抽象基础控制器类的项目中使用第一种方法shouldUse,所有其他适用的控制器都继承自该基础类。希望这会有所帮助。

答案 1 :(得分:0)

查看Laravel Request的生命周期后,我发现在使用Controller类的构造函数时,用户在 Auth Guard 对象中不可用被执行 如果您尝试访问控制器构造函数上的登录用户

public function __construct(Auth $auth, Gate $gate)
{
    $this->auth = $auth;
    $this->gate = $gate;
    $this->middleware('auth:web');
    $this->auth->shouldUse('web');
    $user = $this->auth->user()  // null
}

但是,如果您通过控制器方法访问用户,则将返回用户

public function index($subdomain)
{
    $user = $this->auth->user()->toArray();
}

这是用户var转储的

array:6 [▼
    "id" => "670732c0-6566-11e8-93c6-41f6face77c8"
    "tenant_id" => "66f815e0-6566-11e8-83b2-37a662a96205"
    "name" => "user"
    "email" => "user@aetech.com"
    "created_at" => "2018-06-01 06:38:32"
    "updated_at" => "2018-06-01 06:38:32"
]