为什么InitializeTenancyByDomain不适用于登录过程? [英] Why InitializeTenancyByDomain is not applicable for the login process?
问题描述
这是针对带有Stancl/Tenancy的Jetstream/Livewire支架的Laravel8.x.租户模型或会话设置的初始化无法正常工作.我没做对或者是内在的问题.
This is for Laravel 8.x with Jetstream/Livewire scaffold having Stancl/Tenancy. The initialization of tenant models or session settings not working right. Either I did not do it right or inbuilt problem.
按照Stencl/tenancy v3.x的说明构建整个软件包.我可以按照下面概述的代码看到dd(\ App \ User :: all())
The entire package was built as per instructions of Stencl/tenancy v3.x. I can see the dd(\App\User::all()) as per code outlined below
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function (){
Route::get('/', function () {
dd(\App\User::all()); //can see all users models in tenants table
return view('welcomeTenant');
});
Route::get('/home', [
'middleware' => ['auth'],
'uses' => '\App\Http\Controllers\HomeController@index'
])->name('home');
});
这意味着对我来说InitializeTenancyByDomain正确.
This meant InitializeTenancyByDomain right to me.
当从租户的域中请求登录表单时,例如在rtbs.example.in中,加密的会话/cookie信息未存储在租户的会话表中,即rtbs.sessions.发布登录表单后,它将在中央域(example.in)中寻找没有用户表的用户,因此Central.users表不存在错误.结果,我得到419错误.我暂时禁用了csrf令牌验证来识别此问题.
When a login form is requested from tenant's domain eg. from rtbs.example.in, the encrypted session/cookie info is not stored in sessions table of tenant i.e. rtbs.sessions. When a login form is posted, it is looking for users in central domain (example.in) where users table is not present, hence the central.users table not exist error. As a result I get 419 error. I had disabled the csrf token verification temporarily to identify this problem.
这是问题.为什么InitializeTenancyByDomain不适用于登录过程?我的基本情况是否可能出错?有趣的是,dd(\ App \ User :: all())如果存在于其他任何地方,即如下图所示
This is the issue. Why the InitializeTenancyByDomain is not applicable for the login process? Could there be a fundamental setting wrong with me? Interestingly, the dd(\App\User::all()) if present anywhere else i.e. as show below
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function (){
dd(\App\User::all()); //central-domain.users does not exist error
Route::get('/', function () {
return view('welcomeTenant');
});
Route::get('/home', [
'middleware' => ['auth'],
'uses' => '\App\Http\Controllers\HomeController@index'
])->name('home');
});
抛出相同的SQL异常,即Central-domain.users表不存在.只有当出现在Route :: get('/'...中时,我才能看到正确的模型.
The same sql exception i.e. central-domain.users table does not exist is thrown. Only when present inside the Route::get('/'... i can see the correct models.
推荐答案
我遇到了 Laravel Fortify 的问题,该问题提供了JetStream的后端.仅当我将会话驱动程序从文件更改为数据库时,这才成为问题-尽管这对于我的部署仍然是必需的.
I had this problem with Laravel Fortify, which provides the backend to JetStream. It only became a problem when I changed the session driver to database from file - though this will be necessary for my deployment anyway.
问题在于,Fortify在其控制器的构造方法中广泛使用了依赖项注入.如有关租赁的文档所述,由于Laravel请求的生命周期这些构造函数运行时将不可用.这意味着它们将默认为中央连接,并导致登录失败.
The issue is that Fortify makes extensive use of dependency injection inside the constructor methods of their controllers. As described in the documentation for Tenancy, because of the lifecycle of a Laravel request the tenancy will not be available when these constructors run. This means they will default to the central connection and cause failure to login.
因为我们无法更改Fortify使用构造函数的方式,所以解决方案是将中间件更改为全局,并将对中央域的检查添加到初始化中间件中:
Because we can't change the way Fortify uses constructors, the solution is to change the middleware to be global and add a check for central domains into the initialization middleware:
将 Stancl \ Tenancy \ Middleware \ InitializeTenancyByDomain 复制到 App \ Middleware \ InitializeTenancyByDomain 进行更改:
public function handle($request, Closure $next)
{
//Skip for central domains
if(in_array($request->getHost(), config('tenancy.central_domains'), true)){
return $next($request);
}
return $this->initializeTenancy(
$request, $next, $request->getHost()
);
}
应用程序/Http/内核使用App \ Http \ Middleware \ InitializeTenancyByDomain;
App/Http/Kernel use App\Http\Middleware\InitializeTenancyByDomain;
protected $middleware = [
// ...
InitializeTenancyByDomain::class,
];
配置/强化
use Stancl\Tenancy\Middleware\PreventAccessFromCentralDomains;
'middleware' => [
'web',
PreventAccessFromCentralDomains::class,
],
路线/租户
Route::middleware([
'web',
PreventAccessFromCentralDomains::class,
])->group(function () {
//Your Routes
}
通过此解决方案,Fortify和Stancl Tenancy现在可以与分隔良好的数据库,会话和登录名一起很好地工作.
With this solution Fortify and Stancl Tenancy are now working well together with well separated databases, sesssions and logins.
这篇关于为什么InitializeTenancyByDomain不适用于登录过程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!