如何对主域使用 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 driver 和 admins 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 请求的生命周期后,我发现用户在 Auth 或 Guard[=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"
]
我正在构建一个多租户应用程序,其想法是管理员通过主域 (http://myapp.app) to the dashboard and the regular users access to another dashboard on their respective subdomains (http://tenant-a.myapp.app) 进行访问。
为了实现这一点,我创建了一个使用 session driver 和 admins 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 请求的生命周期后,我发现用户在 Auth 或 Guard[=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"
]