Как использовать на Laravel Guard для основного домена и другое для поддоменов
Я создаю мультитенантное приложение, в котором идея заключается в том, что администраторы получают доступ через основной домен ( http://myapp.app/) к информационной панели, а обычные пользователи - к другой информационной панели в своих соответствующих поддоменах ( http://tenant-a.myapp.app/)
Чтобы добиться этого, я создал специальный сторож (admin), который использует драйвер сеанса и провайдер admin, который является провайдером, который использует eloquent драйвер и администраторы моей таблицы.
// 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, но все еще не работает. Когда я использую объект защиты, у него есть пользователь- член Предполагается, что он содержит зарегистрированного пользователя, но он всегда равен нулю, и если вы собираетесь спросить меня, зачем мне нужен пользователь, это потому, что мне нужно проверить разрешения пользователя
Мои теории таковы, что мой сеанс работает только с основным доменом, а не с субдомианами, или мне нужно указать другой файл 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 ответа
После рассмотрения жизненного цикла запроса Laravel я обнаружил, что пользователь недоступен внутри объектов Auth или Guard, когда выполняется конструктор классов 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"
]
Вы можете попробовать несколько разных подходов, чтобы динамически установить охрану.
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
между проектами с абстрактным базовым классом контроллеров, от которого наследуются все остальные применимые контроллеры. Надеюсь это поможет.