我们可以使用多个具有多种二级域名吗?

发布于 2025-02-09 02:12:58 字数 1174 浏览 2 评论 0原文

我已经使用

例如;我有2个租户Company-ACompany-b,它们是通过Company-a.localhostCompany> Company b的服务。 。 Company-A.Employee.localhost,它应该告诉我 Company-A员工

我尝试在subdoain routeServiceProvider 的路由上使用以下内容:

           Route::middleware('web')
                ->group(base_path('routes/security.php'));

           Route::domain($this->baseDomain('admin'))
                ->middleware('web')
                ->name('admin.')
                ->group(base_path('routes/admin.php'));

           Route::domain($this->baseDomain('employee'))
                ->middleware('web')
                ->name('employee.')
                ->group(base_path('routes/employee.php'));

           private function baseDomain(string $subdomain = ''): string
           {
             if (strlen($subdomain) > 0) {
                $subdomain = "{$subdomain}.";
              }
             return $subdomain . config('app.base_domain');
           }

没有子域,它可以正常工作,但是具有第二级域的路由,它落在基本级域路由上并且没有当前的租户。 我在这里想念什么?这甚至可以实施吗?

谢谢。

I have implemented the simplest example using the Spatie docs for multitenancy, that is working perfectly fine. Now, I intend to use multiple second-level domains for each tenant I have.

For example; I have 2 tenants company-a and company-b and they are being served at company-a.localhost and company-b.localhost, now what I want is that when I visit company-a.admin.localhost, it should tell me COMPANY-A ADMIN and If I visit company-a.employee.localhost, it should tell me COMPANY-A EMPLOYEE.

I have tried using subdomain on routes in RouteServiceProvider like the following:

           Route::middleware('web')
                ->group(base_path('routes/security.php'));

           Route::domain($this->baseDomain('admin'))
                ->middleware('web')
                ->name('admin.')
                ->group(base_path('routes/admin.php'));

           Route::domain($this->baseDomain('employee'))
                ->middleware('web')
                ->name('employee.')
                ->group(base_path('routes/employee.php'));

           private function baseDomain(string $subdomain = ''): string
           {
             if (strlen($subdomain) > 0) {
                $subdomain = "{$subdomain}.";
              }
             return $subdomain . config('app.base_domain');
           }

Without subdomain, it works fine, but the routes with second-level domain, it falls to base level domain route and does not get the current tenant.
What am I missing here? Is this even possible to implement.

Thankyou.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冰魂雪魄 2025-02-16 02:12:58

以路由为例:

 Route::domain('{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   });

绑定字段将为['subdoain','param1','param2'],并且编译的路由将其宣布为

regex => "{^/foo/(?P<param1>[^/]++)/(?P<param2>[^/]++)$}sDu",
hostRegex => "{^(?P<subdomain>[^\.]++)\.example\.com$}sDiu"

>^( ?

但是,通过使用方法,这些正则是不可能的。您可以像在编译路线中那样声明上述路线

 Route::domain('{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   })->where('subdomain', '(.*)');

,Hostregex现在意味着

 hostRegex => "{^(?P<subdomain>(?:.*))\.example\.com$}sDiu"

它将捕获.example.com之前的任何内容。如果您要求Company-A.Admin.example.com$ subdomain将为company-a.admin

您还可以在其域中声明具有两个绑定字段的路线:

 Route::domain('{subsubdomain}.{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   });

如果您希望亚ubsubdomains暗示层次结构,这可能会更有用。

Take, for example, the route:

 Route::domain('{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   });

The binding fields would be ['subdomain', 'param1', 'param2'], and the compiled route would have it's regexes declared as

regex => "{^/foo/(?P<param1>[^/]++)/(?P<param2>[^/]++)$}sDu",
hostRegex => "{^(?P<subdomain>[^\.]++)\.example\.com$}sDiu"

Where ^(?P<subdomain>[^\.]++)\. will explicitly stop capturing when finding a dot, in this case the delimiter between groups.

However, these regexes are overridable by using the where method. You could declare the above route as

 Route::domain('{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   })->where('subdomain', '(.*)');

In the compiled route , the hostRegex would be now

 hostRegex => "{^(?P<subdomain>(?:.*))\.example\.com$}sDiu"

Meaning it will capture anything preceding .example.com. If you requested company-a.admin.example.com, $subdomain would be company-a.admin.

You could also declare a route with two binding fields in its domain:

 Route::domain('{subsubdomain}.{subdomain}.example.com')
   ->get('/foo/{param1}/{param2}',function(Router $router) {
       // do something with it
   });

Which might be more useful if you wanted subsubdomains to imply a hierarchy.

帝王念 2025-02-16 02:12:58

我已经通过使用一些检查来实现这一目标,在ruteserviceProvider中,我没有在route> route上使用实际的domain函数,就像我们正常的IE路由:: domain('foo.bar')。原因是,spatie软件包使用一种中间件spatie \ MultitEnancy \ tenantfinder \ tenantfinder \ domaintenantfinder :: class每当我们与房客comapny一起碰到域时,该> class -a.localhost 。它从主机名中获得了租户IE comapny-a.localhost

    public function findForRequest(Request $request):?Tenant
    {
        $host = $request->getHost();
        return $this->getTenantModel()::whereDomain($host)->first();
    }

在我的routeserviceProvide中:

     $this->routes(function () {
         $class = 'security';
         $middleware = 'web';
         if (Str::contains(request()->getHost(), 'admin')) {
             $class = 'admin';
         } elseif (Str::contains(request()->getHost(), 'employee')) {
             $class = 'employee';
         } elseif (Str::contains(request()->getHost(), 'api')) {
             $class = 'api';
             $middleware = 'api';
         }

         Route::middleware($middleware)
             ->name("$class.")
             ->group(base_path("routes/${class}.php"));
     });

与我的情况一样,我只有这两种二级域,因此,我只是检查了主机名中是否存在此特定关键字,并相应地选择文件和中间件。

我还覆盖了domaintenantfinder类,在supterenancy.php配置文件中:

    public function findForRequest(Request $request): ?Tenant
    {
        $host = $request->getHost();
        $host = str_replace('admin.', '', $host);
        $host = str_replace('employee.', '', $host);
        $host = str_replace('api.', '', $host);
        $tenant = $this->getTenantModel()::whereDomain($host)->first();
        if (empty($tenant)) {
            abort(404);
        }
        return $tenant;
    }

我已经实现了所需的结果,但是,我有一个安全问题,特别是在routeServiceProvider中/代码>逻辑。想法??

I have achieved this by using some checks, in RouteServiceProvider, I have not used the actual domain function on Route like we do normally i.e. Route::domain('foo.bar'). The reason was that, the Spatie package use a kind of middleware Spatie\Multitenancy\TenantFinder\DomainTenantFinder::class which runs whenever we hit the domain with tenant comapny-a.localhost. And it gets the tenant from hostname i.e comapny-a.localhost.

    public function findForRequest(Request $request):?Tenant
    {
        $host = $request->getHost();
        return $this->getTenantModel()::whereDomain($host)->first();
    }

In my RouteServiceProvide:

     $this->routes(function () {
         $class = 'security';
         $middleware = 'web';
         if (Str::contains(request()->getHost(), 'admin')) {
             $class = 'admin';
         } elseif (Str::contains(request()->getHost(), 'employee')) {
             $class = 'employee';
         } elseif (Str::contains(request()->getHost(), 'api')) {
             $class = 'api';
             $middleware = 'api';
         }

         Route::middleware($middleware)
             ->name("$class.")
             ->group(base_path("routes/${class}.php"));
     });

As In my scenario, I had only these 2 kind of second-level domains and so, I just checked if this particular keyword exists in the hostname and choosing the file and middleware accordingly.

I also overrided the DomainTenantFinder class and in multitenancy.php config file:

    public function findForRequest(Request $request): ?Tenant
    {
        $host = $request->getHost();
        $host = str_replace('admin.', '', $host);
        $host = str_replace('employee.', '', $host);
        $host = str_replace('api.', '', $host);
        $tenant = $this->getTenantModel()::whereDomain($host)->first();
        if (empty($tenant)) {
            abort(404);
        }
        return $tenant;
    }

I have acheived the desired outcome, however, I have a security concern, specially in RouteServiceProvider logic. Thought??

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文