1

I want to prevent access to some of my app routes from other domain except listed. It success using below code:

$loginRoutes = function() {
Route::get('/', 'HomeController@index')->name('home');
};

Route::domain('domain1.com')->group($loginRoutes);
Route::domain('domain2.com')->group($loginRoutes);
Route::domain('localhost')->group($loginRoutes);

But the problem is when I call {{route('home')}}, the URL always becomes the domain at the last line of the routes.php(at above case is http://localhost ). How to make it to current domain?

My current solution:

if (isset($_SERVER["HTTP_HOST"]) && $_SERVER["HTTP_HOST"] == "domain1.com") {
Route::domain('domain1.com')->group($loginRoutes);
}elseif (isset($_SERVER["HTTP_HOST"]) && $_SERVER["HTTP_HOST"] == "domain2.com") {
Route::domain('domain2.com')->group($loginRoutes);
}

It's work but I think it's dirty. I have a lot of domains/subdomain and also the routes too.

I need solution on route directly, because I have a lot of routes, if I update each controller it's will take a long time. Maybe edit route provider or laravel vendor code is also no problem.

Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
  • `route()` will return with your application's `APP_URL`. I believe you've set it to localhost right now, so it would return localhost in that case. Also what are you using for your web server? I was thinking, wouldn't it be better to define virtual hosts? – sykez Feb 02 '21 at 16:37
  • @sykez not, it's not depend APP_URL, try it by yourself and you will know. I use Apache, I used wildcard virtual host because we have so many domains and subdomains. Sometimes the domains and subdomains are dynamic, so I cant separate each domain/subdomain – Muhammad Dyas Yaskur Feb 02 '21 at 22:07

5 Answers5

4

I am also using PHP 7.3 and Laravel 5.7 I actually use this routing for my domains. Maybe this is not exactly what you asked, but you can try something like this

// To get the routes from other domains
// Always add the new domains here
$loginRoutes = function() {
    Route::get('/', 'HomeController@index')->name('home');
};

Route::group(array('domain' => 'domain1.com'), $loginRoutes);
Route::group(array('domain' => 'domain2.com'), $loginRoutes);
Route::group(array('domain' => 'domain3.com'), $loginRoutes);

If you want to handle something at the domain level. In your controller (HomeController@index), you can get the current domain and do whatever you want. To get exact domain I have used like this:

class HomeController extends Controller
{ 
   public function index()
   {
      $domain = parse_url(request()->root())['host'];
      if ($domain == 'domain1.com'){
         // do something
      }
      ...
   }
   ...
}

That way I can handle different things for each domain.

Just to make it more complete, we can take the domains from a table/query and dynamically create the routes.

$domains = Cache::get('partners')->where('status', '=', 'A')->where('domain', '<>', '')->all(); 
$loginRoutes = function() {
    Route::get('/', 'HomeController@ index')->name('home');
};
foreach ($domains as $domain) {
    Route::group(array('domain' => $domain->dominio_externo), $loginRoutes);
}

It has been working for me. I hope to help you.

LuizEduardoMPF
  • 876
  • 9
  • 14
0

You can maybe try something like this :

Route::pattern('domainPattern', '(domain1.com|domain2.com|localhost)');
$loginRoutes = function() {
    Route::get('/', 'HomeController@index')->name('home');
};
Route::group(['domain' => '{domainPattern}'], $loginRoutes);
Julien METRAL
  • 1,894
  • 13
  • 30
  • when I tried it make all of $loginRoutes need another parameter. the error said `Missing required parameters for [Route: home] ` why and how to fix it? – Muhammad Dyas Yaskur Mar 27 '19 at 09:53
  • It looks like it's a blade problem, not a route configuration problem like in [this post](https://stackoverflow.com/questions/35259948/laravel-5-2-missing-required-parameters-for-route-user-profile-uri-user-ni) – Julien METRAL Mar 27 '19 at 09:56
  • No, my route dont have any parameter like I posted above. your reference link has parameter but mine is not. – Muhammad Dyas Yaskur Mar 27 '19 at 10:04
0

If I understand your issue, you just want to filter domains. Using regex, you can do it. You could try the following code:

Route::domain('{domain}')->group($loginRoutes)->where('domain', '\b(domain1\.com|domain2\.com|localhost)\b');

Details:

  1. \b: we get exactly the string.
  2. \.: in regex, the character . means any character. So, we have to escape . using backslash.

Note:
You might get an error, because I can not check the results. Let me know any errors you encounter.

Thân LƯƠNG Đình
  • 3,082
  • 2
  • 11
  • 21
0

I want to prevent access to some of my app routes from other domain except listed. It success using below code:

I think you are right with your thoughts about a better, more laravel-core based solution for this problem.

Every route handling method you define in a controller file recieves a request. In standard laravel this is an object of type Illuminate\Http\Request.

You can extend this class with a custom class - let's say "AdminRequest". This extended class than offers authorization methods which will check if the Auth:user has the correct role, session values or whatever you want in your app.

I guess this is more flexible and clean - in your controller you only have to change the definition of the request you recieve in that controller method. Validation messages and everything else can be wrapped in the custom request class.

See this also:

How to Use custom request (make:request)? (laravel) Method App\Http\Requests\Custom::doesExistI does not exist

Extend Request class in Laravel 5

C4pt4inC4nn4bis
  • 586
  • 1
  • 6
  • 18
0

for preventing access to a certain route, its a bad design to inject a Route into these structure:

Route::domain('domain1.com')->group($loginRoutes);
Route::domain('domain2.com')->group($loginRoutes);
Route::domain('localhost')->group($loginRoutes);

since it defines route multiple time, and only the last will be override the others.

you can check this by php artisan route:list .

the laravel way to handle this situation (access management ) is to use middleware

class DomainValid
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $domain = $request->server->get('SERVER_NAME');
        if (in_array($domain , ['domain1.com','domain2.com','localhost'] )) {
            return $next($request);
        }
        abort(403);
    }
}

and use it like this:

use App\Http\Middleware\DomainValid;

Route::get('/', 'HomeController@index')->name('home')->middleware(DomainValid::class);    

so it will be only ONE home route.

Abilogos
  • 4,777
  • 2
  • 19
  • 39