我正在构建一个多租户应用程序,其构想是管理员通过主域(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"
}
}
答案 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"
]