如何对主域使用 Laravel 保护,对子域使用另一个保护

How to use on Laravel guard for the main domain and another for the subdomains

我正在构建一个多租户应用程序,其想法是管理员通过主域 (http://myapp.app) to the dashboard and the regular users access to another dashboard on their respective subdomains (http://tenant-a.myapp.app) 进行访问。

为了实现这一点,我创建了一个使用 session driveradmins provider 的自定义 guard(admin),它是一个自定义提供程序使用 eloquent 驱动程序 和我的 table 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,
   ],
],

在阅读了大量关于身份验证如何工作的文档后,我得到了带有重置密码系统的管理员仪表板工作事件,但部分子域仍然存在一些问题。

租户子域上普通用户的登录似乎正常工作,因为我让我的用户登录,如果我选中记住选项,这会反映在数据库中获取令牌。

最重要的问题是,当我尝试使用身份验证功能(外观或注入)检索用户时,我无法获取用户,该方法总是 return me null。

我已经尝试为 auth 对象指定守卫,但仍然无效。

当我使用 guard 对象 时,它有一个成员 user,它应该包含已登录的用户,但它始终为 null 并且如果你要问我为什么需要用户,那是因为我需要检查用户的权限。

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

我什至不知道我的代码的哪一部分对 post 有用,但是如果您与这个问题有关,欢迎您给我任何启发,如果您需要,请告诉我更多信息或我的一段特定代码。

提前致谢

更新

这是UserController.php

的摘录
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"
  }
 }

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

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
}

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

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

查看 Laravel 请求的生命周期后,我发现用户在 AuthGuard[=21 中不可用=] 对象,当 Controller 类 的构造函数被执行时 如果您尝试访问控制器构造函数上的已登录用户

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();
}

这是转储的用户变量

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"
]