为什么InitializeTenancyByDomain不适用于登录过程? [英] Why InitializeTenancyByDomain is not applicable for the login process?

查看:91
本文介绍了为什么InitializeTenancyByDomain不适用于登录过程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是针对带有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆