Hosting Admin URLs on a Subdomain
Quick tutorial on how to host admin routes on a subdomain.
Admin routing is one of those features in Cake that turns out to be a lot handier than you think it will. I use it all the time, but something about it bothers me.
It's probably just my own paranoia, but hosting the administrative backend of a site on the same domain as the site itself has always felt wrong to me. I doubt the following would improve the security of a site any measurable degree, but (a) it makes me feel better, and (b) it looks nice.
Let's say I'm hosting a new site at example.com, and using Cake's admin routing, I access the admin section at example.com/admin/, but I've also set up admin.example.com, and I want to access it from there instead. When setting up admin.example.com, I want to point it to the same path as example.com itself. Then, in app/config/bootstrap.php, I add the following:
The first part of the if block adds "admin/" to the URL that is parsed by Cake. The second part disables admin-URL access from any other (non-admin) domains. Optionally, instead of just sending a 404 and dying, you could set $_GET["url"] to a path that you know doesn't exist in your site (i.e. "notfound/"), which will make Cake render your "Not Found" page in production mode.
And that's it. The nice thing about this trick is that you can use it for any kind of URL manipluation whatsoever (the SEO possibilities abound).
It's probably just my own paranoia, but hosting the administrative backend of a site on the same domain as the site itself has always felt wrong to me. I doubt the following would improve the security of a site any measurable degree, but (a) it makes me feel better, and (b) it looks nice.
Let's say I'm hosting a new site at example.com, and using Cake's admin routing, I access the admin section at example.com/admin/, but I've also set up admin.example.com, and I want to access it from there instead. When setting up admin.example.com, I want to point it to the same path as example.com itself. Then, in app/config/bootstrap.php, I add the following:
PHP Snippet:
Download code
<?php
if (env("HTTP_HOST") == "admin.example.com") {
$_GET["url"] = "admin/" . $_GET["url"];
} elseif (strpos($_GET["url"], "admin") === 0) {
header ("HTTP/1.0 404 Not Found");
die();
}
?>
The first part of the if block adds "admin/" to the URL that is parsed by Cake. The second part disables admin-URL access from any other (non-admin) domains. Optionally, instead of just sending a 404 and dying, you could set $_GET["url"] to a path that you know doesn't exist in your site (i.e. "notfound/"), which will make Cake render your "Not Found" page in production mode.
And that's it. The nice thing about this trick is that you can use it for any kind of URL manipluation whatsoever (the SEO possibilities abound).
Comments
Comment
1 Love it
Question
2 Using Dynamic Subdomains
I am making an app w/ Cake where I need to allow users to login at theirChosenSubDomain.myApp.com. Sort of like how BaseCamp does it. Can anybody point me in a good direction on this? I know there will be some server configuration involved in addition to messing w/ Cake to make it happen. Any advice? Basically I would need to route/map theirChosenSubDomain.myApp.com to myApp.com/theirChosenSubDomain...
Thanks.
Comment
3 Reply to Dynamic Subdomains
So here's what you do:
First, set up wildcard DNS. In your dns entry, set up *.yourdomain.com to point to the same IP address as www.yourdomain.com. You can find tutorials on wildcard DNS on Google.
Second, you have to set up Apache for wildcard. Put a ServerAlias *.yourdomain.com directive in the VirtualHost for your site in httpd.conf.
Third, and I'm basing this completely on this article, you need to add some code to app/config/bootstrap.php. Here's what I would do:
<?php
// if there's a subdomain and it's not www
if (env("HTTP_HOST") != "www.yourdomain.com" && env("HTTP_HOST") != "yourdomain.com") {
// filter out the .yourdomain.com part
$clientdomain = str_replace(".yourdomain.com", "", env("HTTP_HOST"));
// from the example, add clients/theirdomain/ to the URL
$_GET["url"] = "clients/".$clientdomain."/" . $_GET["url"];
}
?>
Then, create a clients controller, and in routes.php, set up /clients/:clientdomain/ so it will pass the client domain to the display method of the controller.
$Route->connect('/clients/:clientdomain/', array('controller' => 'clients', 'action' => 'display'));
Access the variable subdomain with $this->params['clientdomain'] from the controller.
That's it!
Have Fun!
Eric
Comment
4 Apache wildcard subdomains
Here's a good tutorial on setting up wildcard subdomains on Apache: http://steinsoft.net/index.php?site=Programming/Articles/apachewildcarddomain
As far as the code in the comment above, that's a good way to parse the subdomain out of the URL, but the way routes are generated seems a bit limiting.
Comment
5 Where to add your snippet
i'd love to know where to enter your code.
thanks a lot !
jyrgen
Question
6 How about with Cake IN the subdomain
So far I've been able to do this and hook it up to the DB fine but when I dial up the controller... nuthin. I tried this fix as well, changing out 'admin' for 'dev' but Cake comes back with an error that it cannot locate a dev controller. I think I understand why this is happening, but I'm not sure what to do next.
Comment
7 and for multiple domains
Question
8 Thanks
I would also really appreciate it if someone could share some ideas on managing multiple domains from one app. Thanks!
S :)
Question
9 missing controller error
### part of appcontroller dump
[controller] => AdminusersController
[controllerName] => Adminusers
)
[pageTitle] => Missing Controller
### part of appcontroller dump
the controller name is "Users" and not "Adminusers"
what can i do ?
thanks, jyrgen