We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Redirect in multiple modules application with different subdomains

Hi everyone,

Based on the Phalcon MVC Examples, i started to develop a multiple modules application with the attached folders structure.

Each module is attached to a router group (front, back, api) with their own subdomain (www.myapp.com, app.myapp.com and api.myapp.com).

Controllers in the back module directory extends the BackController in the regular Controllers directory. Controllers in the front module directory extends the FrontController in the regular Controllers directory.

To be sure that the user can access to the backend (which is a private resource), i have the following check done

class BackController extends ControllerBase
{

  public function beforeExecuteRoute(Dispatcher $dispatcher): bool {

    // User is logged ?
    $identity = $this->auth->getIdentity();

    if (empty($identity) && !is_array($identity)) {

      // Redirect user to login
      $this->flash->error('error_user_not_logged');

      return false;

    }

    return true;

  }

  ...

 }

I want to be able to redirect the user from the subdomain app.myapp.com to www.myapp.com/signin when the user i not logged. It seems to be a basic need, but for some reason i'm not able to find the correct way to do it. I thought using the Manager as a provider listening to the event 'dispatch:beforeForward' would help, but nor fowarding or redirect using route name change the subdomain.

Anyone can help ? Thanks, take care

app phalcon



5.1k
edited Sep '20

Thanks, appreciate but won't resolve the issue. Here's my router.php conf

$public = new Group([
  'controller' => 'public',
  'module' => 'front'
]);
$public->setHostname('www.' . getenv('APP_DOMAIN'));

$public->add('/signin', [
  'action' => 'signin',
  'controller' => 'index'
])->setName('signin');

$private = new Group([
  'controller' => 'back',
  'module' => 'back'
]);
$private->setHostname('app.' . getenv('APP_DOMAIN'));

$private->add('/', [
  'action' => 'index',
  'controller' => 'index'
])->setName('dashboard');

...

BackController is protected using the beforeExecuteRoute to control if user is auth. So if i type app.myapp.com, i'm supposed to be redirect to www.myapp.com/signin But for some reasons, using setHostName doesn't seems to be taken when $dispatcher->forward(...) or $this->response->redirect(...). Maybe i'm doing wrong ?



8.4k
edited Sep '20

you will need to make an external http redirect

$this->response->redirect('www.myapp.com/signin', true); or $this->response->redirect('https://www.myapp.com/signin');

response->redirect() will check for :// in the first paramater if its not in the string and the second paramater is false will attempt to call url->get()

i'm not 100% sure but in your case making internal forwards will look within $private defined routes which '/signin' is defined in $public



5.1k

Ok, so indeed, i'm supposed to pass the full url. I'll have to define const or maybe play with $url->setBaseUri() regarding the module/route i'm trying to get/load. Thanks for you help !



8.4k
edited Sep '20

i would suggest against altering the base uri as it will break any url made using Url::get()

why not just use getenv('APP_DOMAIN') when redirecting

also $this->response->redirect() can work with controller and action

$this->response->redirect('controller/action')



5.1k
edited Sep '20

The fact is, if i try to reach app.myapp.comnot logged i'm supposed to be redirect to www.myapp.com/signin. Using $this->url->get(['for' => 'signin']); will generate the following url /signin without considering my router hostname attached to my public or private group. getenv('APP_DOMAIN) only contains myapp.com. This is the reason i though altering the baseUri would be better...